docling-project/docling · error · RuntimeError

Incompatible file format {self.input_format} was passed to I

Error message

Incompatible file format {self.input_format} was passed to ImageDocumentBackend.

What it means

ImageDocumentBackend.__init__ raises RuntimeError when in_doc.input_format is anything other than InputFormat.IMAGE. The class deliberately bypasses PdfDocumentBackend.__init__ to avoid image-to-PDF conversion, so it can only serve direct image input; passing PDF or other formats is a caller contract violation.

Source

Thrown at docling/backend/image_backend.py:151

          the image→PDF conversion and any pypdfium2 usage.
        - Handles multi-page TIFF by extracting frames eagerly to separate
          Image objects to keep thread-safety when pages process in parallel.
    """

    def __init__(
        self,
        in_doc: InputDocument,
        path_or_stream: Union[BytesIO, Path],
        options: Optional[PdfBackendOptions] = None,
    ):
        if options is None:
            options = PdfBackendOptions()
        # Bypass PdfDocumentBackend.__init__ to avoid image→PDF conversion
        AbstractDocumentBackend.__init__(self, in_doc, path_or_stream, options)
        self.options: PdfBackendOptions = options

        if self.input_format not in {InputFormat.IMAGE}:
            raise RuntimeError(
                f"Incompatible file format {self.input_format} was passed to ImageDocumentBackend."
            )

        # Load frames eagerly for thread-safety across pages
        self._frames: List[Image.Image] = []
        try:
            with Image.open(self.path_or_stream) as img:  # type: ignore[arg-type]
                # Handle multi-frame and single-frame images
                # - multiframe formats: TIFF, GIF, ICO
                # - singleframe formats: JPEG (.jpg, .jpeg), PNG (.png), BMP, WEBP (unless animated), HEIC
                frame_count = getattr(img, "n_frames", 1)

                if frame_count > 1:
                    for i in range(frame_count):
                        img.seek(i)
                        self._frames.append(img.copy().convert("RGB"))
                else:
                    self._frames.append(img.convert("RGB"))

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Let DocumentConverter / the backend registry choose the backend from the detected format
  2. If constructing manually, ensure InputDocument.input_format == InputFormat.IMAGE
  3. Use PdfDocumentBackend (or the appropriate backend) for non-image input

Example fix

# before
backend = ImageDocumentBackend(in_doc, path)  # in_doc.input_format == InputFormat.PDF

# after
assert in_doc.input_format == InputFormat.IMAGE
backend = ImageDocumentBackend(in_doc, path)
Defensive patterns

Strategy: validation

Validate before calling

from docling.datamodel.base_models import InputFormat

assert in_doc.input_format == InputFormat.IMAGE, (
    f'ImageDocumentBackend requires IMAGE input, got {in_doc.input_format}'
)

Type guard

def accepts_image_backend(in_doc) -> bool:
    return in_doc.input_format == InputFormat.IMAGE

Prevention

When it happens

Trigger: Constructing ImageDocumentBackend with an InputDocument whose input_format is InputFormat.PDF or another format; usually caused by manually instantiating backends instead of letting the format-registry/dispatch pick the right one.

Common situations: Custom pipelines that hardcode a backend class; format-detection bugs that label a PDF as IMAGE; refactors that swap backend classes without updating the InputDocument format.

Related errors


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