BerriAI/litellm · error · ValueError

pages must be between {PAGES_MIN} and {PAGES_MAX}, got {self

Error message

pages must be between {PAGES_MIN} and {PAGES_MAX}, got {self.pages}

What it means

Companion validation in the apiserpent search defaults: when 'pages' (page count for multi-page fetches) is provided it must be an int in [1, 10]. None is allowed and means single-page; anything outside the range raises at construction time in __post_init__.

Source

Thrown at litellm/llms/apiserpent/search/defaults.py:49

    """

    engine: SearchEngine = "google"
    country: str = "us"
    num: int = 10
    format: ResponseFormat = "full"
    pages: int | None = None
    freshness: Freshness | None = None
    safe: SafeSearch | None = None
    language: str | None = None
    pixel_position: bool | None = None

    def __post_init__(self) -> None:
        # num's deep-search floor (NUM_MIN_DEEP) is endpoint-specific and enforced
        # in the transform layer; here we only bound the absolute range.
        if not NUM_MIN <= self.num <= NUM_MAX:
            raise ValueError(f"num must be between {NUM_MIN} and {NUM_MAX}, got {self.num}")
        if self.pages is not None and not PAGES_MIN <= self.pages <= PAGES_MAX:
            raise ValueError(f"pages must be between {PAGES_MIN} and {PAGES_MAX}, got {self.pages}")

    def to_request_params(self) -> dict:
        """Return non-None fields as request params, booleans lowercased."""
        params: Final[dict] = {}
        for key, value in asdict(self).items():
            if value is None:
                continue
            params[key] = str(value).lower() if isinstance(value, bool) else value
        return params

    @classmethod
    def field_names(cls) -> set:
        return set(cls.__dataclass_fields__.keys())


QUICK_SEARCH_PATH: Final = "/api/search/quick"
DEEP_SEARCH_PATH: Final = "/api/search"

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Set pages to a value from 1 to 10, or leave it out entirely for single-page behavior.
  2. Compute pages as min(10, ceil(desired_results / num)).
  3. If you truly need more than 10 pages, issue multiple search calls client-side.

Example fix

# before
params = SearchDefaults(num=50, pages=25)

# after
params = SearchDefaults(num=100, pages=5)  # same 500-result budget within limits
Defensive patterns

Strategy: validation

Validate before calling

PAGES_MIN, PAGES_MAX = 1, 10

def clamp_pages(pages: int | None) -> int | None:
    if pages is None:
        return None
    return max(PAGES_MIN, min(pages, PAGES_MAX))

Type guard

def is_valid_pages(pages: object) -> bool:
    return pages is None or (isinstance(pages, int) and not isinstance(pages, bool) and 1 <= pages <= 10)

Try / catch

try:
    params = SearchDefaults(num=num, pages=pages)
except ValueError:
    params = SearchDefaults(num=num, pages=max(1, min(pages or 1, 10)))

Prevention

When it happens

Trigger: Constructing SearchDefaults with pages=0, pages=11+, or a negative value. pages=0 (perhaps intended as 'no paging') is rejected — omit the field or use None instead.

Common situations: Config files with pages: 0 as a 'disabled' sentinel; arithmetic that derives pages from a desired total result count (e.g. total_results/10 with a large total); copying example configs with unsupported values.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/0af708821f42c3aa. Report an issue: GitHub.