{"record":{"id":"0975e8c5b1edbd7b","repo":"BerriAI/litellm","slug":"invalid-pages-list-for-azure-document-intelligen","errorCode":null,"errorMessage":"Invalid `pages` list for Azure Document Intelligence: {pages!r}. Expected tokens like '1' or '3-5'.","messagePattern":"Invalid `pages` list for Azure Document Intelligence: (.+?)\\. Expected tokens like '1' or '3-5'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/azure_ai/ocr/document_intelligence/transformation.py","lineNumber":164,"sourceCode":"                    f\"Invalid `pages` string for Azure Document Intelligence: \"\n                    f\"{pages!r}. Expected format like '1-3,5,7-9'.\"\n                )\n            return pages.replace(\" \", \"\")\n\n        if isinstance(pages, list):\n            if len(pages) == 0:\n                return \"\"\n            if any(isinstance(p, bool) for p in pages):\n                raise ValueError(\"`pages` must be integers, not booleans\")\n            if all(isinstance(p, int) for p in pages):\n                if any(p < 0 for p in pages):\n                    raise ValueError(\"`pages` integers must be >= 0 (Mistral 0-based indices)\")\n                # Mistral 0-based -> Azure 1-based.\n                return \",\".join(str(p + 1) for p in sorted(set(pages)))\n            if all(isinstance(p, str) for p in pages):\n                joined: Final = \",\".join(p.strip() for p in pages)\n                if not pages_pattern.match(joined):\n                    raise ValueError(\n                        f\"Invalid `pages` list for Azure Document Intelligence: \"\n                        f\"{pages!r}. Expected tokens like '1' or '3-5'.\"\n                    )\n                return joined\n\n        raise ValueError(\"`pages` must be a list[int] (0-based, Mistral-style) or a string like '1-3,5,7-9'.\")\n\n    @staticmethod\n    def _normalize_features_param(features: object) -> str:\n        \"\"\"\n        Convert a caller-provided `features` value to Azure DI's query-string\n        form (comma-joined feature names, e.g. \"keyValuePairs,languages\").\n\n        Accepted inputs:\n          - list[str]: feature names like [\"keyValuePairs\", \"languages\"].\n          - str: a single feature name or comma-separated names.\n        \"\"\"\n        invalid_features_error: Final = ValueError(","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/azure_ai/ocr/document_intelligence/transformation.py#L146-L182","documentation":"Raised when `pages` is a list of strings but the comma-joined result fails Azure's page-range regex — i.e. the individual tokens are not plain page numbers or hyphenated ranges. List[str] input is treated as Azure-native 1-based tokens, stripped, joined, and validated as a whole before being sent. Tokens like '1..3', '1;', 'page1', or an empty string trigger this.","triggerScenarios":"Calling azure_ai doc-intelligence OCR with pages=[\"1..3\"], [\"1\", \"\"], [\"page 2\"], or [\"1-3\", \"abc\"] — any list[str] whose joined form doesn't match ^\\d+(-\\d+)?(,\\d+(-\\d+)?)*$ after stripping.","commonSituations":"Splitting a user-supplied string on commas without validating tokens (leaving empties); forwarding tokens from another API's syntax; shell/env-var parsing inserting stray characters.","solutions":["Use tokens that are single 1-based page numbers or ranges: ['1', '3-5'] or ['1-3', '7'].","If you have 0-based indices, switch to list[int] and let LiteLLM convert.","Validate/clean tokens before the call: strip whitespace, drop empties, ensure digits-only or digit-digit."],"exampleFix":"# before\npages = [p.strip() for p in user_input.split(\",\") if True]  # may leave '' or '1..2'\nlitellm.aocr_document(model=..., document=doc, pages=pages)\n\n# after\nimport re\npages = [p.strip() for p in user_input.split(\",\") if re.fullmatch(r\"\\d+(-\\d+)?\", p.strip())]\nlitellm.aocr_document(model=..., document=doc, pages=pages)","handlingStrategy":"validation","validationCode":"import re\nTOKEN_RE = re.compile(r\"^\\d+(-\\d+)?$\")\ndef valid_pages_tokens(pages: list[str]) -> bool:\n    return all(isinstance(p, str) and TOKEN_RE.match(p.strip()) for p in pages)","typeGuard":"def is_str_pages_list(v: object) -> bool:\n    import re\n    return isinstance(v, list) and all(\n        isinstance(p, str) and re.fullmatch(r\"\\d+(-\\d+)?\", p.strip()) for p in v\n    )","tryCatchPattern":null,"preventionTips":["Validate each token with ^\\d+(-\\d+)?$ after stripping.","Drop empty tokens when splitting a user string on commas."],"tags":["azure","document-intelligence","ocr","validation","pages"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}