BerriAI/litellm · error · ValueError

Invalid `pages` string for Azure Document Intelligence: {pag

Error message

Invalid `pages` string for Azure Document Intelligence: {pages!r}. Expected format like '1-3,5,7-9'.

What it means

Thrown while normalizing the `pages` parameter for Azure Document Intelligence OCR when the caller passes a string that does not match the expected Azure page-range syntax (digits and hyphenated ranges, comma-separated, e.g. '1-3,5,7-9'). The string is validated against a regex before being forwarded to Azure, because Azure DI only accepts that exact query-string format. Any deviation (letters, double commas, 'page 1', semicolons) is rejected before the request is sent.

Source

Thrown at litellm/llms/azure_ai/ocr/document_intelligence/transformation.py:145

    @staticmethod
    def _normalize_pages_param(pages: Any) -> str:
        """
        Convert a caller-provided `pages` value to Azure DI's query-string
        form. Azure expects 1-based page numbers, grammar: `^(\\d+(-\\d+)?)(,\\s*(\\d+(-\\d+)?))*$`.

        Accepted inputs:
          - list[int]: Mistral-style 0-based indices. Converted to 1-based
            and joined (e.g. [0,1,2] -> "1,2,3").
          - list[str]: tokens like "1" or "3-5". Validated, joined as-is
            (treated as Azure-native, i.e. 1-based).
          - str: already in Azure format. Validated and whitespace-stripped.
        """
        pages_pattern: Final = re.compile(r"^\s*\d+(-\d+)?(\s*,\s*\d+(-\d+)?)*\s*$")

        if isinstance(pages, str):
            if not pages_pattern.match(pages):
                raise ValueError(
                    f"Invalid `pages` string for Azure Document Intelligence: "
                    f"{pages!r}. Expected format like '1-3,5,7-9'."
                )
            return pages.replace(" ", "")

        if isinstance(pages, list):
            if len(pages) == 0:
                return ""
            if any(isinstance(p, bool) for p in pages):
                raise ValueError("`pages` must be integers, not booleans")
            if all(isinstance(p, int) for p in pages):
                if any(p < 0 for p in pages):
                    raise ValueError("`pages` integers must be >= 0 (Mistral 0-based indices)")
                # Mistral 0-based -> Azure 1-based.
                return ",".join(str(p + 1) for p in sorted(set(pages)))
            if all(isinstance(p, str) for p in pages):
                joined: Final = ",".join(p.strip() for p in pages)
                if not pages_pattern.match(joined):

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Format the string as comma-separated 1-based pages or ranges: '1-3,5,7-9' (spaces around commas are stripped, other whitespace only at the ends).
  2. If you have 0-based Mistral-style indices, pass a list[int] instead — LiteLLM converts to 1-based for you.
  3. Sanitize user-provided page input before passing it as `pages`.

Example fix

# before
result = litellm.aocr_document(model="azure_ai/doc-intelligence/prebuilt-read", document=doc, pages="pages 1 to 3")

# after
result = litellm.aocr_document(model="azure_ai/doc-intelligence/prebuilt-read", document=doc, pages="1-3")
Defensive patterns

Strategy: validation

Validate before calling

import re
PAGES_RE = re.compile(r"^\s*\d+(-\d+)?(\s*,\s*\d+(-\d+)?)*\s*$")
def valid_pages_str(pages: str) -> bool:
    return bool(PAGES_RE.match(pages))

Type guard

def is_azure_pages_string(v: object) -> bool:
    import re
    return isinstance(v, str) and bool(re.match(r"^\s*\d+(-\d+)?(\s*,\s*\d+(-\d+)?)*\s*$", v))

Prevention

When it happens

Trigger: Calling litellm.oclr/aocr with model 'azure_ai/doc-intelligence/...' and optional_params={"pages": "1;3;5"} or "1..3" or "pages 1-3" or "1,,2" — anything failing ^\s*\d+(-\d+)?(\s*,\s*\d+(-\d+)?)*\s*$. Note ranges here are Azure-native 1-based.

Common situations: Porting code from another OCR API whose pages syntax differs; user input passed through unvalidated; copy-pasting '1 - 3' style with stray characters; assuming 0-based or interval syntax like '1:3'.

Related errors


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