docling-project/docling · error · EbcdicDecodeError
No record layout matches record type {record_type!r}.
Error message
No record layout matches record type {record_type!r}. What it means
EbcdicDecodeError raised during record framing: the backend decoded the record-type prefix field and called layout.select(record_type), but no EbcdicRecordLayout in the layout declares that type value, so it cannot know how to parse the record body. The message shows the decoded record_type value — comparing it with your layout's declared record types is the whole debugging step.
Source
Thrown at docling/backend/ebcdic_backend.py:167
self, data: bytes, offset: int, end: int
) -> tuple[EbcdicRecordLayout, int, int]:
"""Consume the record prefix and resolve the schema and body size."""
layout = self._layout
length: Union[int, None] = None
record_type: Union[str, None] = None
if (field := layout.record_length_field) is not None:
chunk = self._take(data, offset, field.size, end, field.name)
length = int(self._decoder.decode(chunk, field))
offset += field.size
if (field := layout.record_type_field) is not None:
chunk = self._take(data, offset, field.size, end, field.name)
record_type = str(self._decoder.decode(chunk, field))
offset += field.size
record = layout.select(record_type)
if record is None:
raise EbcdicDecodeError(
f"No record layout matches record type {record_type!r}."
)
size = record.size if length is None else length - layout.prefix_size
if size < 0:
raise EbcdicDecodeError(
f"Record length {length} is shorter than the "
f"{layout.prefix_size}-byte record prefix."
)
return record, size, offset
@staticmethod
def _take(data: bytes, offset: int, size: int, end: int, name: str) -> bytes:
if offset + size > end:
raise EbcdicDecodeError(
f"Input ends inside {name!r}: {end - offset} of {size} bytes left."
)
return data[offset : offset + size]View on GitHub (pinned to 61d76f1ff3)
Solutions
- Compare the record_type value in the message with the type values declared on your records — add a matching EbcdicRecordLayout (or extend its type list) if the data legitimately contains that variant.
- If the value looks like mojibake, fix record_type_field: correct size, offsets, and encoding (e.g. decode via zoned decimal if the field is numeric).
- Confirm record_length_field handling: a wrong length shifts the offset at which the type is read.
- Print the raw prefix bytes around the failing record and reconcile them against the copybook.
Example fix
# before
layout = EbcdicLayout(
records=[EbcdicRecordLayout(name='detail', record_types={'D'})],
record_type_field=EbcdicField(name='RT', type=EbcdicFieldType.STRING, size=1),
)
# data contains 'H' header records -> No record layout matches record type 'H'
# after
records=[
EbcdicRecordLayout(name='header', record_types={'H'}, fields=[...]),
EbcdicRecordLayout(name='detail', record_types={'D'}, fields=[...]),
] Defensive patterns
Strategy: try-catch
Validate before calling
# Enumerate record types present in data vs declared in layout:
def undeclared_record_types(layout, data: bytes) -> set[str]:
declared = set().union(*(r.record_types for r in layout.records))
seen = set()
for rec_start in iter_record_starts(data): # your framing walk
seen.add(decode_type_field(data, rec_start))
return seen - declared # non-empty predicts this error Try / catch
from docling.backend.ebcdic_backend import EbcdicDecodeError
try:
conv.convert(src, pipeline_options=opts)
except EbcdicDecodeError as e:
if "No record layout matches" in str(e):
rt = extract_record_type(str(e))
add_record_variant_to_layout(opts.layout, rt) # then retry
else:
raise Prevention
- Declare layouts for every record type the feed can emit, including rare variants.
- Verify record_type_field size/offset/encoding against the copybook.
- Log unexpected record types and extend layouts rather than dropping records silently.
When it happens
Trigger: Data contains a record type token not declared in layout.records (new record variant, regional record, or versioned format); the record_type_field is mis-declared (wrong size/offset/type/encoding) so a valid type decodes to garbage; records where the type field overlaps other data because offsets shifted.
Common situations: Layout built from an old copybook while the feed added new record types; record_type declared as STRING but stored as zoned/packed numeric (or vice versa); fixed-vs-variable length prefix confusion causing the type bytes to be read from the wrong position.
Related errors
- Cannot decode field {field.name!r} of type {field.type.value
- Record length {length} is shorter than the {layout.prefix_si
- Input ends inside {name!r}: {end - offset} of {size} bytes l
- Unknown EBCDIC codec {encoding!r}.
- Could not initialize the EBCDIC backend for file with hash {
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/e4369c4454568f92.
Report an issue: GitHub.