docling-project/docling · error · RuntimeError

PagePreprocessingModel returned unexpected number of pages

Error message

PagePreprocessingModel returned unexpected number of pages

What it means

The preprocessing stage of StandardPdfPipeline runs PagePreprocessingModel over a batch of valid pages and asserts that the number of processed pages returned equals the number of pages submitted. A length mismatch means the preprocessing model changed the page count, breaking the ThreadedItem bookkeeping that maps results back to (run_id, page_no, conv_res). As with error 341, this is an internal invariant guard that fires when a custom or modified preprocessing model violates its contract.

Source

Thrown at docling/pipeline/standard_pdf_pipeline.py:529

            try:
                if _log.isEnabledFor(logging.DEBUG):
                    _t_start = time.time()
                    _t_mono = time.monotonic()
                pages = [page for _, page in valid]
                processed_pages = list(
                    self.model(valid[0][0].conv_res, pages)  # type: ignore[arg-type]
                )
                if _log.isEnabledFor(logging.DEBUG):
                    _log.debug(
                        "PIPELINE_PROFILING Stage preprocess: run_id=%d pages=%s start=%.3f end=%.3f duration=%.3fs",
                        rid,
                        [it.page_no for it, _ in valid],
                        _t_start,
                        time.time(),
                        time.monotonic() - _t_mono,
                    )
                if len(processed_pages) != len(pages):
                    raise RuntimeError(
                        "PagePreprocessingModel returned unexpected number of pages"
                    )
                for idx, processed_page in enumerate(processed_pages):
                    result.append(
                        ThreadedItem(
                            payload=processed_page,
                            run_id=rid,
                            page_no=valid[idx][0].page_no,
                            conv_res=valid[idx][0].conv_res,
                        )
                    )
            except Exception as exc:
                _log.error(
                    "Stage preprocess failed for run %d, pages %s: %s",
                    rid,
                    [it.page_no for it, _ in valid],
                    exc,
                    exc_info=False,

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Return one processed page per input page from the custom preprocessing model; mark unprocessed pages with an empty/failed payload rather than omitting them.
  2. If page filtering is genuinely needed, do it before handing pages to the pipeline (filter conv_res.pages) rather than inside the model.
  3. Align docling and docling-core versions (pip install -U docling docling-core) so the model contract matches.
  4. Reproduce with stock pipeline options to confirm the customization is the cause.

Example fix

# before
class MyPreprocessModel(PagePreprocessingModel):
    def __call__(self, conv_res, pages):
        return [p for p in pages if not is_blank(p)]  # drops pages -> mismatch

# after
class MyPreprocessModel(PagePreprocessingModel):
    def __call__(self, conv_res, pages):
        return [empty_processed_page(p) if is_blank(p) else p for p in pages]
Defensive patterns

Strategy: try-catch

Try / catch

try:
    result = converter.convert(doc)
except RuntimeError as e:
    if 'unexpected number of pages' in str(e):
        # preprocessing model changed page count; return 1:1 results instead
        ...

Prevention

When it happens

Trigger: Overriding or replacing the preprocessing model so it filters, merges, or drops pages; a custom pipeline that injects its own PagePreprocessingModel subclass returning fewer results than input pages; version skew between docling-core model code and pipeline code.

Common situations: Adding a custom preprocessing step (e.g. blank-page removal) that skips pages instead of returning an empty processed page; running with locally patched docling-core where the model return shape changed; mixing docling and docling-core versions from different releases.

Related errors


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