{"record":{"id":"15f1b40991ddd4bb","repo":"docling-project/docling","slug":"could-not-initialize-the-ebcdic-backend-for-file-w","errorCode":null,"errorMessage":"Could not initialize the EBCDIC backend for file with hash {self.document_hash}.","messagePattern":"Could not initialize the EBCDIC backend for file with hash (.+?)\\.","errorType":"exception","errorClass":"DocumentLoadError","httpStatus":null,"severity":"error","filePath":"docling/backend/ebcdic_backend.py","lineNumber":232,"sourceCode":"        in_doc: InputDocument,\n        path_or_stream: Union[BytesIO, Path],\n        options: Union[EbcdicBackendOptions, None] = None,\n    ) -> None:\n        if options is None:\n            options = EbcdicBackendOptions()\n        super().__init__(in_doc, path_or_stream, options)\n\n        self.layout = self._resolve_layout()\n        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(","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/backend/ebcdic_backend.py#L214-L250","documentation":"EbcdicDocumentBackend.__init__ raises this DocumentLoadError when reading the raw bytes from the input fails: it calls BytesIO.getvalue() or Path.read_bytes(), catching OSError and ValueError. OSError covers missing/unreadable files; ValueError covers I/O on closed streams (a closed BytesIO raises ValueError). Note the backend deliberately reads from the constructor argument, not self.path_or_stream, because unload() clears the latter — so this error is purely about obtaining the bytes.","triggerScenarios":"Passing a Path that does not exist or has no read permission; passing a BytesIO that was closed before conversion (buf.close() then convert); reading from a broken network mount. It fires before any EBCDIC decoding — a separate error covers a missing layout (EbcdicBackendOptions.layout / layout_file).","commonSituations":"Streams closed by cleanup code (with-block exited, temp-file buffers closed) before docling reads them; paths from config/queues pointing at deleted files; containerized runs hitting a permissions change on mounted volumes.","solutions":["Check the file exists and is readable: Path(p).is_file() and os.access(p, os.R_OK).","Do not close the BytesIO before handing it to the converter; if you must manage lifetime, pass fresh BytesIO(data).","Inspect e.__cause__: OSError -> path/permission issue; ValueError -> closed stream.","For network mounts, verify availability (mount status) before the conversion job starts."],"exampleFix":"# before\nbuf = BytesIO(data)\nprocess(buf)\nbuf.close()\nconv.convert(buf, pipeline_options=opts)  # ValueError: closed file -> error 19\n\n# after\nconv.convert(BytesIO(data), pipeline_options=opts)  # fresh open stream","handlingStrategy":"validation","validationCode":"from pathlib import Path\nfrom io import BytesIO\nimport os\n\ndef readable_source(src: Path | BytesIO) -> bool:\n    if isinstance(src, Path):\n        return src.is_file() and os.access(src, os.R_OK)\n    return isinstance(src, BytesIO) and not src.closed  # closed streams raise ValueError","typeGuard":"from io import BytesIO\nfrom pathlib import Path\n\ndef is_acceptable_source(src) -> bool:\n    return (isinstance(src, Path) and src.is_file()) or (isinstance(src, BytesIO) and not src.closed)","tryCatchPattern":"from docling.exceptions import DocumentLoadError\ntry:\n    conv.convert(src, pipeline_options=opts)\nexcept DocumentLoadError as e:\n    if isinstance(e.__cause__, ValueError):\n        conv.convert(BytesIO(data), pipeline_options=opts)  # fresh, open stream\n    elif isinstance(e.__cause__, OSError):\n        fix_permissions_or_skip(src)","preventionTips":["Do not close BytesIO streams before conversion; hand over ownership.","Check Path.is_file() and read permission before enqueuing files.","In batch jobs, verify mounts are alive before processing queued paths."],"tags":["ebcdic","document-load","io","closed-stream"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}