docling-project / docling-project/docling-core
KeyValueItem/FormItem serializers are unimplemented: Markdown emits a placeholder, DocLang emits nothing
- Dominant language
- HTML
- Stars
- 282
- Forks
- 214
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 21
Description
`MarkdownKeyValueSerializer` and `MarkdownFormSerializer` (`transforms/serializer/markdown.py`) each carry an explicit `# TODO add actual implementation` and return a literal placeholder (`create_ser_result(text="", span_source=item)`, and `` for forms). `DocLangKeyValueSerializer` and `DocLangFormSerializer` (`transforms/serializer/doclang.py`) are documented no-ops — "Return an empty result for key/value items" — so DocLang loses the content with zero trace, not even a placeholder.
Minimal repro (docling-core 2.94.1): a document built via `add_key_values(graph=GraphData(cells=[GraphCell(label=KEY, text="Name"), GraphCell(label=VALUE, text="John Doe")], links=[GraphLink(label=TO_VALUE, ...)]))` exports as:
- Markdown → ``
- DocLang → `` — completely empty
`add_form(...)` behaves identically. The `GraphData` payload itself round-trips fine through `.docling.json`; only the two derived serialization formats lose it. The equivalent construction via the modern field-region API (`add_field_region()` / `add_field_key()` / `add_field_value()`, introduced in #519 / v2.70.0) serializes correctly on both formats, so this looks like the legacy family was left behind when the modern one shipped, rather than a general serializer gap.
Related: #486 tracks "consolidate FormItem/KeyValueItem" as done (via #519), but the legacy types remain constructible in the schema with unimplemented serializers rather than being removed or migrated. Separately, `DoclingDocument._migrate_to_field_regions` (`types/doc/document.py`) is a complete migration implementation for exactly this case, but nothing calls it anywhere in `docling_core` or `docling` — it appears to be dead code that would resolve this if it were wired up (e.g. on deserialization).
Two candidate fixes: implement the four serializers to render the legacy family (mapping it onto the same output shape the modern family already produces), or call the existing `_migrate_to_field_regions` on construction/validation so legacy items become field regions before any serializer sees them.
---
Found while auditing a downstream project's DocLang export pipeline; happy to share the exact synthetic `DoclingDocument` construction used to reproduce this if useful.
Contributor guide
Research direction
Start with transforms/serializer/markdown.py and transforms/serializer/doclang.py, comparing the legacy serializers with the modern field-region output. Then inspect DoclingDocument._migrate_to_field_regions in types/doc/document.py and the add_key_values/add_form and field-region APIs; done means legacy items preserve their content in both Markdown and DocLang, with regression coverage for the reported construction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100