{"record":{"id":"4aabd2faa04f9d54","repo":"docling-project/docling","slug":"the-ebcdic-backend-needs-a-layout-set-either-ebcd","errorCode":null,"errorMessage":"The EBCDIC backend needs a layout: set either EbcdicBackendOptions.layout or EbcdicBackendOptions.layout_file.","messagePattern":"The EBCDIC backend needs a layout: set either EbcdicBackendOptions\\.layout or EbcdicBackendOptions\\.layout_file\\.","errorType":"exception","errorClass":"DocumentLoadError","httpStatus":null,"severity":"error","filePath":"docling/backend/ebcdic_backend.py","lineNumber":241,"sourceCode":"        try:\n            # Read from the argument rather than self.path_or_stream, which\n            # unload() clears to None.\n            self.content = (\n                path_or_stream.getvalue()\n                if isinstance(path_or_stream, BytesIO)\n                else path_or_stream.read_bytes()\n            )\n        except (OSError, ValueError) as exc:\n            raise DocumentLoadError(\n                \"Could not initialize the EBCDIC backend for file with hash \"\n                f\"{self.document_hash}.\"\n            ) from exc\n\n    def _resolve_layout(self) -> EbcdicLayout:\n        if self.options.layout is not None:\n            return self.options.layout\n        if self.options.layout_file is None:\n            raise DocumentLoadError(\n                \"The EBCDIC backend needs a layout: set either \"\n                \"EbcdicBackendOptions.layout or EbcdicBackendOptions.layout_file.\"\n            )\n        try:\n            return EbcdicLayout.model_validate_json(\n                self.options.layout_file.read_bytes()\n            )\n        except (OSError, ValueError) as exc:\n            raise DocumentLoadError(\n                f\"Could not read the EBCDIC layout {self.options.layout_file}.\"\n            ) from exc\n\n    @override\n    def is_valid(self) -> bool:\n        return bool(self.content)\n\n    @classmethod\n    @override","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/backend/ebcdic_backend.py#L223-L259","documentation":"The EBCDIC backend requires a record layout describing fixed-width fields before it can parse mainframe data. _resolve_layout() raises DocumentLoadError when EbcdicBackendOptions.layout is None and layout_file is also None. Without a layout the backend cannot map EBCDIC byte columns to table cells, so it refuses to load rather than guessing.","triggerScenarios":"Creating an EBCDIC backend / converting a file with InputFormat.EBCDIC while EbcdicBackendOptions() is left at defaults, or when options are built but neither the `layout` (in-memory EbcdicLayout) nor `layout_file` (Path to JSON) attribute is assigned.","commonSituations":"Teams adopting the EBCDIC backend copy example code that omits layout setup; CI pipelines that pass a generic EbcdicBackendOptions() for all formats; refactors that drop the layout_file argument.","solutions":["Set EbcdicBackendOptions.layout to an EbcdicLayout instance built in code","Or set EbcdicBackendOptions.layout_file to a Path of JSON matching the EbcdicLayout schema (validated with EbcdicLayout.model_validate_json)","If loading from a file, verify the path exists and the JSON validates before passing it to the backend"],"exampleFix":"# before\nopts = EbcdicBackendOptions()\ndoc = DocumentConverter(format_options={InputFormat.EBCDIC: PdfFormatOptions(backend_opts=opts)}).convert(src)\n\n# after\nopts = EbcdicBackendOptions(layout=EbcdicLayout.model_validate_json(Path('layout.json').read_text()))\n# or: opts = EbcdicBackendOptions(layout_file=Path('layout.json'))","handlingStrategy":"validation","validationCode":"from docling.datamodel.base_models import InputFormat\nfrom docling.datamodel.pipeline_options import PdfFormatOptions\nfrom docling.backend.ebcdic_backend import EbcdicBackendOptions\n\nopts = EbcdicBackendOptions()\nassert opts.layout is not None or opts.layout_file is not None, (\n    'EBCDIC conversion requires EbcdicBackendOptions.layout or .layout_file'\n)","typeGuard":null,"tryCatchPattern":"try:\n    result = converter.convert(src)\nexcept DocumentLoadError as exc:\n    if 'needs a layout' in str(exc):\n        raise ConfigError('EBCDIC layout not configured') from exc\n    raise","preventionTips":["Centralize EbcdicBackendOptions construction in one factory that always sets a layout","Fail fast on missing layout at app startup instead of at first document"],"tags":["ebcdic","configuration","mainframe","backend-options"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}