docling-project/docling · error · RuntimeError

Unexpected: {type(self.path_or_stream)=}

Error message

Unexpected: {type(self.path_or_stream)=}

What it means

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.

Source

Thrown at docling/backend/xml/doclang_backend.py:43

    @classmethod
    @override
    def supports_pagination(cls) -> bool:
        return False

    @classmethod
    @override
    def supported_formats(cls) -> set[InputFormat]:
        return {InputFormat.XML_DOCLANG}

    def _get_doc_or_err(self) -> Union[DoclingDocument, Exception]:
        try:
            if isinstance(self.path_or_stream, Path):
                text = self.path_or_stream.read_text(encoding="utf-8")
            elif isinstance(self.path_or_stream, BytesIO):
                text = self.path_or_stream.getvalue().decode("utf-8")
            else:
                raise RuntimeError(f"Unexpected: {type(self.path_or_stream)=}")

            doc = DocLangDocDeserializer().deserialize_str(text)
            doc.origin = DocumentOrigin(
                filename=self.file.name or "file",
                mimetype="application/xml",
                binary_hash=self.document_hash,
            )
            return doc
        except Exception as e:
            return e

    @override
    def convert(self) -> DoclingDocument:
        if isinstance(self._doc_or_err, DoclingDocument):
            return self._doc_or_err

        raise self._doc_or_err

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Pass Path(path_str) for file-based input.
  2. Pass BytesIO(raw_bytes) for in-memory input (encode text to UTF-8 bytes first).
  3. Validate the type before constructing the backend.
  4. Use DocumentConverter, which accepts paths and streams and routes them correctly.

Example fix

# before
backend = DoclangBackend(in_doc, open("doc.xml"))  # file object -> RuntimeError

# after
backend = DoclangBackend(in_doc, Path("doc.xml"))
# or in-memory:
backend = DoclangBackend(in_doc, BytesIO(xml_str.encode("utf-8")))
Defensive patterns

Strategy: type-guard

Validate before calling

from pathlib import Path
from io import BytesIO

def acceptable_source(src) -> bool:
    return isinstance(src, (Path, BytesIO))

Type guard

from pathlib import Path
from io import BytesIO
from typing import TypeGuard, Union

def is_backend_source(src: object) -> TypeGuard[Union[Path, BytesIO]]:
    return isinstance(src, (Path, BytesIO))

Try / catch

try:
    doc = backend.convert()
except Exception as e:
    if "Unexpected: type(self.path_or_stream)" in str(e):
        raise TypeError("doclang backend needs Path or BytesIO") from e
    raise

Prevention

When it happens

Trigger: 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().

Common situations: Passing open(path).read() (str) instead of bytes; forwarding a file handle from caller code; string-path convenience habits.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/2624f3937b965af8. Report an issue: GitHub.