docling-project/docling · error · ValueError
Invalid page range: start must be ≥ 1 and end must be ≥ star
Error message
Invalid page range: start must be ≥ 1 and end must be ≥ start.
What it means
The PageRange type is a Tuple[int, int] with an AfterValidator that enforces a 1-based, ordered range: the start must be >= 1 and the end must be >= the start. It is used for settings like page_range when converting documents, and the default is (1, sys.maxsize). Any out-of-order or zero/negative bound raises this ValueError at settings construction.
Source
Thrown at docling/datamodel/settings.py:12
import sys
from contextlib import contextmanager
from pathlib import Path
from typing import Annotated, Iterator, Optional, Tuple
from pydantic import AfterValidator, BaseModel
from pydantic_settings import BaseSettings, SettingsConfigDict
def _validate_page_range(v: Tuple[int, int]) -> Tuple[int, int]:
if v[0] < 1 or v[1] < v[0]:
raise ValueError(
"Invalid page range: start must be ≥ 1 and end must be ≥ start."
)
return v
PageRange = Annotated[Tuple[int, int], AfterValidator(_validate_page_range)]
DEFAULT_PAGE_RANGE: PageRange = (1, sys.maxsize)
class DocumentLimits(BaseModel):
max_num_pages: int = sys.maxsize
max_file_size: int = sys.maxsize
page_range: PageRange = DEFAULT_PAGE_RANGE
class BatchConcurrencySettings(BaseModel):
doc_batch_size: int = 1 # Number of documents processed in one batch. Should be >= doc_batch_concurrencyView on GitHub (pinned to 61d76f1ff3)
Solutions
- Use 1-based inclusive bounds with start <= end, e.g. page_range=(3, 10).
- Clamp computed ranges: page_range=(max(1, start), max(start, end)).
- For 'up to the last page', pass the default (1, sys.maxsize) or omit page_range.
Example fix
# before result = converter.convert(pdf, page_range=(0, 5)) # 0 is invalid # after result = converter.convert(pdf, page_range=(1, 5))
Defensive patterns
Strategy: validation
Validate before calling
def valid_page_range(r: tuple[int, int]) -> bool:
start, end = r
return start >= 1 and end >= start
assert valid_page_range((start, end)), "page_range must be 1-based with start <= end" Type guard
def is_valid_page_range(r: tuple[int, int]) -> bool:
s, e = r
return isinstance(s, int) and isinstance(e, int) and 1 <= s <= e Try / catch
try:
converter.convert(doc, page_range=(s, e))
except ValidationError as e:
if "Invalid page range" in str(e):
s2, e2 = max(1, s), max(max(1, s), e)
result = converter.convert(doc, page_range=(s2, e2))
else:
raise Prevention
- Remember docling page ranges are 1-based inclusive, unlike Python slices.
- Clamp dynamically computed ranges, especially end = total - k on short documents.
When it happens
Trigger: Passing page_range=(0, 10), page_range=(5, 3), or page_range=(-1, 5) to DocumentConverter.convert / convert_all, or setting a page-range-typed field on a settings object. Tuple order matters: it is (start, end), not (end, start).
Common situations: Treating page ranges as 0-based (coming from Python slice conventions) and passing start=0; swapping the tuple elements so start > end; computing end dynamically (e.g. num_pages - 2) and going below start on very short documents.
Related errors
- Cannot convert Box Note with hash {self.document_hash}: no '
- Cannot convert doc with {self.document_hash} because the bac
- docling-parse could not load document {self.document_hash}:
- docling-parse could not load document {self.document_hash}.
- ThreadedDoclingParseDocumentBackend only supports iter_pages
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/e78018f842e101fb.
Report an issue: GitHub.