docling-project/docling · error · RuntimeError

Unexpected: {type(self.path_or_stream)=}

Error message

Unexpected: {type(self.path_or_stream)=}

What it means

DoclangArchiveBackend's internal loader only accepts a pathlib.Path or io.BytesIO as path_or_stream; any other type (str path, open file object, temp file handle) hits the else-branch RuntimeError. The error is captured by _get_doc_or_err and later surfaced as the conversion error, so the f-string type detail is preserved in the message.

Source

Thrown at docling/backend/xml/doclang_archive_backend.py:54

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

    def _get_doc_or_err(self) -> Union[DoclingDocument, Exception]:
        try:
            if isinstance(self.path_or_stream, Path):
                doc = DoclingDocument.load_from_doclang_archive(self.path_or_stream)
            elif isinstance(self.path_or_stream, BytesIO):
                self._temp_dir = Path(tempfile.mkdtemp(prefix="docling_dclx_"))
                archive_path = self._temp_dir / (self.file.name or "document.dclx")
                archive_path.write_bytes(self.path_or_stream.getvalue())
                artifacts_dir = self._temp_dir / "artifacts"
                doc = DoclingDocument.load_from_doclang_archive(
                    archive_path,
                    artifacts_dir=artifacts_dir,
                )
            else:
                raise RuntimeError(f"Unexpected: {type(self.path_or_stream)=}")

            doc.origin = DocumentOrigin(
                filename=self.file.name or "file",
                mimetype=_DCLX_MIMETYPE,
                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

    @override

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Wrap the value: pass Path(my_string) instead of the string.
  2. Read the bytes yourself and pass BytesIO(data) for in-memory handling.
  3. Type-check before constructing the backend (isinstance against (Path, BytesIO)).
  4. Prefer DocumentConverter.convert(source), which normalizes accepted sources for you.

Example fix

# before
backend = DoclangArchiveBackend(in_doc, "/data/report.dclx")  # str -> RuntimeError

# after
from pathlib import Path
backend = DoclangArchiveBackend(in_doc, Path("/data/report.dclx"))
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 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("pass Path or BytesIO to doclang archive backend") from e
    raise

Prevention

When it happens

Trigger: Constructing DoclangArchiveBackend (or converting a .dclx doclang archive) with path_or_stream of an unexpected type — most commonly a plain string filename instead of Path, or a raw file object opened by caller code.

Common situations: Custom pipelines that pass str paths for convenience; adapters that forward an already-open file; code migrated from an API that accepted strings.

Related errors


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