docling-project/docling · error · RuntimeError
Model {self.name} returned wrong number of pages
Error message
Model {self.name} returned wrong number of pages What it means
In the threaded execution path of StandardPdfPipeline, each pipeline stage model is invoked with a batch of pages and must return exactly one result per input page. After the model call, a strict mismatch guard compares len(processed_pages) with len(pages) and raises this RuntimeError if the model dropped, merged, or added pages. It signals a broken stage model implementation (typically a custom or experimental model), not a user input problem.
Source
Thrown at docling/pipeline/standard_pdf_pipeline.py:365
continue
pages: list[Page] = [payload for _, payload in pages_with_payloads]
if _log.isEnabledFor(logging.DEBUG):
_t_start = time.time()
_t_mono = time.monotonic()
processed_pages = list(self.model(good[0].conv_res, pages)) # type: ignore[arg-type]
if _log.isEnabledFor(logging.DEBUG):
_log.debug(
"PIPELINE_PROFILING Stage %s: run_id=%d pages=%s start=%.3f end=%.3f duration=%.3fs",
self.name,
rid,
[it.page_no for it in good],
_t_start,
time.time(),
time.monotonic() - _t_mono,
)
if len(processed_pages) != len(pages): # strict mismatch guard
raise RuntimeError(
f"Model {self.name} returned wrong number of pages"
)
for idx, page in enumerate(processed_pages):
result.append(
ThreadedItem(
payload=page,
run_id=rid,
page_no=good[idx].page_no,
conv_res=good[idx].conv_res,
)
)
except Exception as exc:
_log.error(
"Stage %s failed for run %d: %s", self.name, rid, exc, exc_info=True
)
for it in good:
it.is_failed = True
it.error = excView on GitHub (pinned to 61d76f1ff3)
Solutions
- Make the custom stage model return exactly one result per page it is given, including error/empty payloads for pages it could not process.
- If you don't need custom models, remove any monkey-patching or overridden model classes so stock docling models are used.
- Pin/align docling versions so stage models and pipeline code come from the same release.
- Report the issue upstream if stock models with unmodified inputs trigger it, including the stage name in the message.
Example fix
# before
class MyModel:
def __call__(self, conv_res, page_batch):
return [self._process_all_pages_once(conv_res, page_batch)] # 1 result for N pages
# after
class MyModel:
def __call__(self, conv_res, page_batch):
return [self._process_one(conv_res, p) for p in page_batch] # N results for N pages Defensive patterns
Strategy: try-catch
Try / catch
try:
result = converter.convert(doc)
except RuntimeError as e:
if 'wrong number of pages' in str(e):
# custom stage model broke the 1-result-per-page contract; fix the model
... Prevention
- Custom stage models must return exactly one payload per input page.
- Don't monkey-patch stock docling models in production code.
- Keep docling and docling-core versions pinned together.
When it happens
Trigger: Plugging a custom model into a StandardPdfPipeline stage whose __call__ returns a list with a different length than the pages it received; a stage that filters out pages (e.g. skips pages it cannot parse) inside the threaded worker; monkey-patched or subclassed models that aggregate page results.
Common situations: Extending docling with a custom layout or OCR model that returns one item per document instead of one per page; upgrading docling versions where a stage model's return contract changed; experimental models that lazily skip failed pages instead of returning a failure payload.
Related errors
- PagePreprocessingModel returned unexpected number of pages
- {pipeline_name} does not support ThreadedDoclingParseDocumen
- No pipeline could be initialized for format {format}
- No pipeline could be initialized for {in_doc.file}.
- Extraction failed for: {ext_res.input.file} with status: {ex
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/a11678c3b047a1c6.
Report an issue: GitHub.