MarkdownKeyValueSerializer and MarkdownFormSerializer (transforms/serializer/markdown.py) each carry an explicit # TODO add actual implementation and return a literal placeholder (create_ser_result(text="<!-- missing-key-value-item -->", span_source=item), and <!-- missing-form-item --> 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 →
<!-- missing-key-value-item -->
- DocLang →
<doclang version="0.7"></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.
MarkdownKeyValueSerializerandMarkdownFormSerializer(transforms/serializer/markdown.py) each carry an explicit# TODO add actual implementationand return a literal placeholder (create_ser_result(text="<!-- missing-key-value-item -->", span_source=item), and<!-- missing-form-item -->for forms).DocLangKeyValueSerializerandDocLangFormSerializer(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:<!-- missing-key-value-item --><doclang version="0.7"></doclang>— completely emptyadd_form(...)behaves identically. TheGraphDatapayload 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 indocling_coreordocling— 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_regionson 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
DoclingDocumentconstruction used to reproduce this if useful.