{"record":{"id":"1821b65042a0296e","repo":"BerriAI/litellm","slug":"num-must-be-between-num-min-and-num-max-got","errorCode":null,"errorMessage":"num must be between {NUM_MIN} and {NUM_MAX}, got {self.num}","messagePattern":"num must be between (.+?) and (.+?), got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/apiserpent/search/defaults.py","lineNumber":47,"sourceCode":"    the rest are always sent so behavior is deterministic regardless of any\n    server-side defaults.\n    \"\"\"\n\n    engine: SearchEngine = \"google\"\n    country: str = \"us\"\n    num: int = 10\n    format: ResponseFormat = \"full\"\n    pages: int | None = None\n    freshness: Freshness | None = None\n    safe: SafeSearch | None = None\n    language: str | None = None\n    pixel_position: bool | None = None\n\n    def __post_init__(self) -> None:\n        # num's deep-search floor (NUM_MIN_DEEP) is endpoint-specific and enforced\n        # in the transform layer; here we only bound the absolute range.\n        if not NUM_MIN <= self.num <= NUM_MAX:\n            raise ValueError(f\"num must be between {NUM_MIN} and {NUM_MAX}, got {self.num}\")\n        if self.pages is not None and not PAGES_MIN <= self.pages <= PAGES_MAX:\n            raise ValueError(f\"pages must be between {PAGES_MIN} and {PAGES_MAX}, got {self.pages}\")\n\n    def to_request_params(self) -> dict:\n        \"\"\"Return non-None fields as request params, booleans lowercased.\"\"\"\n        params: Final[dict] = {}\n        for key, value in asdict(self).items():\n            if value is None:\n                continue\n            params[key] = str(value).lower() if isinstance(value, bool) else value\n        return params\n\n    @classmethod\n    def field_names(cls) -> set:\n        return set(cls.__dataclass_fields__.keys())\n\n\nQUICK_SEARCH_PATH: Final = \"/api/search/quick\"","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/apiserpent/search/defaults.py#L29-L65","documentation":"Constructor validation for the apiserpent (SerpentAPI) search defaults dataclass. 'num' (results per request) must be an int in [1, 100]; the __post_init__ hook rejects anything outside that absolute range with a ValueError. The deep-search floor of 10 is enforced separately in the transform layer, so values 1-9 pass here but may be clamped later for deep endpoints.","triggerScenarios":"Instantiating the search defaults with num=0, a negative number, or num>100 — e.g. num=200 to 'get more results', or num=0 to mean 'unlimited'.","commonSituations":"Porting configs from APIs that allow num=0 or 1000; user-facing search UIs letting users request arbitrary result counts; pagination math that computes num as page_size * page and overflows the cap.","solutions":["Clamp num to 1..100 before constructing the object.","For more results, use the 'pages' parameter (1..10) instead of a huge num.","Remember deep-search endpoints enforce a floor of 10 — pass >= 10 for deep search."],"exampleFix":"# before\nparams = SearchDefaults(num=200)\n\n# after\nparams = SearchDefaults(num=100, pages=2)  # 2 pages of 100 instead of num=200","handlingStrategy":"validation","validationCode":"NUM_MIN, NUM_MAX = 1, 100\n\ndef clamp_num(num: int) -> int:\n    return max(NUM_MIN, min(num, NUM_MAX))","typeGuard":"def is_valid_num(num: object) -> bool:\n    return isinstance(num, int) and not isinstance(num, bool) and 1 <= num <= 100","tryCatchPattern":"try:\n    params = SearchDefaults(num=num)\nexcept ValueError:\n    params = SearchDefaults(num=min(100, max(1, num)))","preventionTips":["Clamp user-supplied result counts to 1..100 before constructing search params.","Use pages (1..10) for more results instead of large num.","For deep search, remember the separate floor of 10."],"tags":["apiserpent","search","validation","pagination"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}