{"record":{"id":"949b074eac68e044","repo":"docling-project/docling","slug":"unsupported-input-type-type-self-path-or-stream","errorCode":null,"errorMessage":"Unsupported input type: {type(self.path_or_stream)}","messagePattern":"Unsupported input type: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"docling/backend/email_backend.py","lineNumber":111,"sourceCode":"            self.is_msg = raw.startswith(_MSG_MAGIC)\n            if self.is_msg:\n                raw = self._msg_to_rfc822_bytes(raw)\n            self.mail = mailparser.parse_from_bytes(raw)\n\n            self.valid = self.mail is not None\n        except ImportError:\n            raise\n        except Exception as exc:\n            raise DocumentLoadError(\n                f\"Could not initialize email backend for file with hash {self.document_hash}.\"\n            ) from exc\n\n    def _read_bytes(self) -> bytes:\n        if isinstance(self.path_or_stream, BytesIO):\n            return self.path_or_stream.getvalue()\n        if isinstance(self.path_or_stream, Path):\n            return self.path_or_stream.read_bytes()\n        raise TypeError(f\"Unsupported input type: {type(self.path_or_stream)}\")\n\n    @staticmethod\n    def _header_safe(value: str) -> str:\n        # Email header values must be single-line; collapse CR/LF to spaces so a\n        # crafted .msg cannot inject headers and EmailMessage does not reject it.\n        return value.replace(\"\\r\", \" \").replace(\"\\n\", \" \").strip()\n\n    @staticmethod\n    def _msg_to_rfc822_bytes(data: bytes) -> bytes:\n        \"\"\"Project an Outlook ``.msg`` (OLE2/CFB) onto RFC 822 bytes.\n\n        python-oxmsg reads the MAPI message; we assemble a standard\n        ``email.message.EmailMessage`` from it so the ``.msg`` path shares the\n        exact body, HTML, address, and attachment handling used for ``.eml``\n        input.\n        \"\"\"\n        if not _OXMSG_AVAILABLE:\n            raise ImportError(_MSG_INSTALL_HINT) from _OXMSG_IMPORT_ERROR","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/backend/email_backend.py#L93-L129","documentation":"EmailDocumentBackend._read_bytes() only accepts BytesIO or Path inputs and raises TypeError for anything else (str paths, file objects opened in text mode, TemporaryFile wrappers, etc.). Because the call sits inside the init try-block, callers normally see it wrapped in the email backend's DocumentLoadError, with the TypeError as __cause__.","triggerScenarios":"Passing a string path instead of pathlib.Path, an open() file object, an io.FileIO, or any stream type other than BytesIO (e.g. io.StringIO) as path_or_stream to the email backend.","commonSituations":"Wrapping Docling in a service that forwards urllib/tempfile handles; legacy code using os.path strings; tests using StringIO for text fixtures.","solutions":["Convert str paths to pathlib.Path before calling the API","Wrap other binary file objects: BytesIO(open(p,'rb').read())","Never pass StringIO or text-mode handles; the backend needs bytes"],"exampleFix":"# before\nbackend = EmailDocumentBackend(in_doc, '/data/mail.eml')  # str not accepted\n\n# after\nfrom pathlib import Path\nbackend = EmailDocumentBackend(in_doc, Path('/data/mail.eml'))\n# or for streams: EmailDocumentBackend(in_doc, BytesIO(raw_bytes))","handlingStrategy":"type-guard","validationCode":"from io import BytesIO\nfrom pathlib import Path\n\ndef normalize(src):\n    if isinstance(src, str):\n        return Path(src)\n    if isinstance(src, Path):\n        return src\n    if isinstance(src, BytesIO):\n        return src\n    if hasattr(src, 'read'):\n        return BytesIO(src.read())\n    raise TypeError(f'unsupported source: {type(src)!r}')","typeGuard":"def is_accepted_source(src) -> bool:\n    return isinstance(src, (BytesIO, Path))","tryCatchPattern":null,"preventionTips":["Normalize all inputs to Path or BytesIO at your service boundary","Never forward raw open() handles or StringIO to Docling backends"],"tags":["email","type-error","api-contract"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}