{"record":{"id":"6dcff4df84b1b9e4","repo":"docling-project/docling","slug":"record-type-field-is-required-for-a-layout-with-se","errorCode":null,"errorMessage":"record_type_field is required for a layout with several records","messagePattern":"record_type_field is required for a layout with several records","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/datamodel/backend_options.py","lineNumber":556,"sourceCode":"        ]\n\n    @property\n    def prefix_size(self) -> int:\n        \"\"\"Length in bytes of the prefix read ahead of every record.\"\"\"\n        return sum(item.size for item in self.prefix_fields)\n\n    def select(self, record_type: Optional[str]) -> Optional[EbcdicRecordLayout]:\n        \"\"\"Return the schema matching a record-type value, if any.\"\"\"\n        if self.record_type_field is None:\n            return self.records[0]\n        return next(\n            (item for item in self.records if item.selector == record_type), None\n        )\n\n    @model_validator(mode=\"after\")\n    def _validate_records(self) -> \"EbcdicLayout\":\n        if len(self.records) > 1 and self.record_type_field is None:\n            raise ValueError(\n                \"record_type_field is required for a layout with several records\"\n            )\n        if self.record_type_field is not None:\n            selectors = [item.selector for item in self.records]\n            if None in selectors:\n                raise ValueError(\n                    \"every record needs a selector when record_type_field is set\"\n                )\n            if len(set(selectors)) != len(selectors):\n                raise ValueError(\"record selectors must be unique\")\n        return self\n\n\nclass EbcdicBackendOptions(BaseBackendOptions):\n    \"\"\"Options specific to the EBCDIC backend.\"\"\"\n\n    kind: Annotated[Literal[\"ebcdic\"], Field(exclude=True, repr=False)] = \"ebcdic\"\n    encoding: Annotated[","sourceCodeStart":538,"sourceCodeEnd":574,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/datamodel/backend_options.py#L538-L574","documentation":"Pydantic model_validator on EbcdicLayout: when the layout declares more than one record definition (self.records has length > 1) but record_type_field is None, there is no way to decide which record schema applies to each physical record, so validation fails. Multi-record EBCDIC files require a field whose value selects the record type.","triggerScenarios":"Building an EbcdicLayout(records=[EbcdicRecordLayout(...), EbcdicRecordLayout(...)]) without setting record_type_field. Common when converting fixed-width EBCDIC files that mix header/detail/trailer record types.","commonSituations":"Mainframe exports (e.g., IBM system files) with multiple record formats per file; users copying a single-record example and adding a second record without adding the discriminator field.","solutions":["Set record_type_field to the name of the field whose value distinguishes record types (e.g., record_type_field='REC_TYPE').","Give every record a distinct selector value matching that field's values.","If the file truly has one record format, keep only one entry in records."],"exampleFix":"# before\nlayout = EbcdicLayout(\n    records=[header_rec, detail_rec],  # no discriminator -> ValueError\n)\n\n# after\nlayout = EbcdicLayout(\n    record_type_field='REC_TYPE',\n    records=[\n        EbcdicRecordLayout(selector='H', fields=[...]),\n        EbcdicRecordLayout(selector='D', fields=[...]),\n    ],\n)","handlingStrategy":"validation","validationCode":"def layout_is_coherent(records, record_type_field):\n    if len(records) > 1 and record_type_field is None:\n        return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    layout = EbcdicLayout(**cfg)\nexcept ValidationError as e:\n    if 'record_type_field is required' in str(e):\n        cfg['record_type_field'] = infer_discriminator_field(cfg['records'])\n        layout = EbcdicLayout(**cfg)","preventionTips":["Whenever a layout has multiple record types, identify the discriminator field up front.","Encode layouts in versioned JSON with a schema that requires record_type_field when records > 1.","Know your source file: multi-format mainframe records always need a type field."],"tags":["ebcdic","validation","pydantic","mainframe"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}