{"record":{"id":"2624f3937b965af8","repo":"docling-project/docling","slug":"unexpected-type-self-path-or-stream-2624f3","errorCode":null,"errorMessage":"Unexpected: {type(self.path_or_stream)=}","messagePattern":"Unexpected: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"docling/backend/xml/doclang_backend.py","lineNumber":43,"sourceCode":"\n    @classmethod\n    @override\n    def supports_pagination(cls) -> bool:\n        return False\n\n    @classmethod\n    @override\n    def supported_formats(cls) -> set[InputFormat]:\n        return {InputFormat.XML_DOCLANG}\n\n    def _get_doc_or_err(self) -> Union[DoclingDocument, Exception]:\n        try:\n            if isinstance(self.path_or_stream, Path):\n                text = self.path_or_stream.read_text(encoding=\"utf-8\")\n            elif isinstance(self.path_or_stream, BytesIO):\n                text = self.path_or_stream.getvalue().decode(\"utf-8\")\n            else:\n                raise RuntimeError(f\"Unexpected: {type(self.path_or_stream)=}\")\n\n            doc = DocLangDocDeserializer().deserialize_str(text)\n            doc.origin = DocumentOrigin(\n                filename=self.file.name or \"file\",\n                mimetype=\"application/xml\",\n                binary_hash=self.document_hash,\n            )\n            return doc\n        except Exception as e:\n            return e\n\n    @override\n    def convert(self) -> DoclingDocument:\n        if isinstance(self._doc_or_err, DoclingDocument):\n            return self._doc_or_err\n\n        raise self._doc_or_err\n","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/backend/xml/doclang_backend.py#L25-L61","documentation":"DoclangBackend (XML doclang format) accepts only pathlib.Path or io.BytesIO for path_or_stream; anything else (str, open file, another stream type) reaches the else-branch and raises RuntimeError('Unexpected: ...'), which _get_doc_or_err captures and re-surfaces at conversion time.","triggerScenarios":"Building DoclangBackend or converting a doclang XML document with path_or_stream that is neither Path nor BytesIO — e.g. a str path or an io.TextIOWrapper from open().","commonSituations":"Passing open(path).read() (str) instead of bytes; forwarding a file handle from caller code; string-path convenience habits.","solutions":["Pass Path(path_str) for file-based input.","Pass BytesIO(raw_bytes) for in-memory input (encode text to UTF-8 bytes first).","Validate the type before constructing the backend.","Use DocumentConverter, which accepts paths and streams and routes them correctly."],"exampleFix":"# before\nbackend = DoclangBackend(in_doc, open(\"doc.xml\"))  # file object -> RuntimeError\n\n# after\nbackend = DoclangBackend(in_doc, Path(\"doc.xml\"))\n# or in-memory:\nbackend = DoclangBackend(in_doc, BytesIO(xml_str.encode(\"utf-8\")))","handlingStrategy":"type-guard","validationCode":"from pathlib import Path\nfrom io import BytesIO\n\ndef acceptable_source(src) -> bool:\n    return isinstance(src, (Path, BytesIO))","typeGuard":"from pathlib import Path\nfrom io import BytesIO\nfrom typing import TypeGuard, Union\n\ndef is_backend_source(src: object) -> TypeGuard[Union[Path, BytesIO]]:\n    return isinstance(src, (Path, BytesIO))","tryCatchPattern":"try:\n    doc = backend.convert()\nexcept Exception as e:\n    if \"Unexpected: type(self.path_or_stream)\" in str(e):\n        raise TypeError(\"doclang backend needs Path or BytesIO\") from e\n    raise","preventionTips":["Never forward str paths or open file handles to backend constructors.","Encode text content to bytes and wrap in BytesIO for in-memory doclang XML."],"tags":["doclang","xml","type-error","api-misuse","backends"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}