BerriAI/litellm · error · ValueError
Expected document dict, got {type(document)}
Error message
Expected document dict, got {type(document)} What it means
Raised in transform_ocr_request when the `document` argument for Azure Document Intelligence OCR is not a dict. LiteLLM's OCR interface follows the Mistral format, where document must be a mapping like {'type': 'document_url', 'document_url': ...}; passing a bare string URL, bytes, or a pydantic object hits this check before any request is built.
Source
Thrown at litellm/llms/azure_ai/ocr/document_intelligence/transformation.py:359
}
OR
{
"base64Source": "base64_encoded_content"
}
Args:
model: Model name
document: Document dict from user (Mistral format)
optional_params: Already mapped optional parameters
headers: Request headers
Returns:
OCRRequestData with JSON data
"""
verbose_logger.debug("Azure Document Intelligence transform_ocr_request - model: %s", model)
if not isinstance(document, dict):
raise ValueError(f"Expected document dict, got {type(document)}")
# Extract document URL from Mistral format
doc_type: Final = document.get("type")
document_url = None
if doc_type == "document_url":
document_url = document.get("document_url", "")
elif doc_type == "image_url":
document_url = document.get("image_url", "")
else:
raise ValueError(f"Invalid document type: {doc_type}. Must be 'document_url' or 'image_url'")
if not document_url:
raise ValueError("Document URL is required")
# Build Azure DI request
data: Final[dict[str, Any]] = {}
View on GitHub (pinned to 6c2dcb801b)
Solutions
- Wrap the source in a Mistral-style dict: {'type': 'document_url', 'document_url': <url>} for files, or {'type': 'image_url', 'image_url': <url or data URI>} for images.
- If building the dict from a pydantic model, call .model_dump() first.
- Check the LiteLLM OCR docs example for the exact document shape.
Example fix
# before
resp = litellm.aocr_document(model="azure_ai/doc-intelligence/prebuilt-read", document="https://x.com/f.pdf")
# after
resp = litellm.aocr_document(
model="azure_ai/doc-intelligence/prebuilt-read",
document={"type": "document_url", "document_url": "https://x.com/f.pdf"},
) Defensive patterns
Strategy: type-guard
Validate before calling
def is_document_dict(v: object) -> bool:
return isinstance(v, dict) and v.get("type") in ("document_url", "image_url") and bool(v.get("document_url") or v.get("image_url")) Type guard
from typing import TypeIs
def is_document_dict(v: object) -> TypeIs[dict]:
return isinstance(v, dict) Prevention
- Always build the document dict with the {'type': ..., url-key} wrapper.
- Call .model_dump() on pydantic objects before passing as document.
When it happens
Trigger: Calling litellm OCR with document="https://example.com/file.pdf" (plain string), document=b'...', or a non-dict object instead of {'type': 'document_url', 'document_url': 'https://...'} or {'type': 'image_url', 'image_url': 'data:...;base64,...'}.
Common situations: Migrating from an SDK that takes a URL string directly; passing a pydantic model that wasn't dumped; forgetting the {'type': ..., url-key} wrapper when copying examples.
Related errors
- Invalid document type: {doc_type}. Must be 'document_url' or
- Document URL is required
- Invalid `pages` string for Azure Document Intelligence: {pag
- `pages` integers must be >= 0 (Mistral 0-based indices)
- Invalid `pages` list for Azure Document Intelligence: {pages
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/d08b23c3aeca32c5.
Report an issue: GitHub.