BerriAI/litellm · error · ValueError
OCR response usage_info is None
Error message
OCR response usage_info is None
What it means
OCRResponse carries pricing data in its usage_info field. If the response passed to the OCR cost calculator has usage_info=None (provider returned no usage, or the transformation didn't populate it), LiteLLM refuses to compute cost and raises ValueError since pages/credits are unknown.
Source
Thrown at litellm/cost_calculator.py:1822
model: str - model name
custom_llm_provider: Optional[str] - custom LLM provider
response: Optional[Any] - response object
Returns:
Tuple[float, float]: cost of OCR processing
(Parent function requires a tuple, so we return a tuple. Cost is only in the first element.)
"""
from litellm.llms.base_llm.ocr.transformation import OCRResponse
#########################################################
# validate it's an OCR response
#########################################################
if response is None or not isinstance(response, OCRResponse):
raise ValueError(f"response must be of type OCRResponse got type={type(response)}")
if response.usage_info is None:
raise ValueError("OCR response usage_info is None")
try:
model_info: ModelInfo | None = litellm.get_model_info(model=model, custom_llm_provider=custom_llm_provider)
except Exception:
model_info = None
credits: Final = getattr(response.usage_info, "credits", None)
cost_per_credit = None
if model_info is not None:
cost_per_credit = model_info.get("ocr_cost_per_credit")
if credits is not None and cost_per_credit is not None:
return cost_per_credit * credits, 0.0
ocr_cost_per_page: float | None = None
if model_info is not None:
ocr_cost_per_page = model_info.get("ocr_cost_per_page")
pages_processed: Final = response.usage_info.pages_processedView on GitHub (pinned to 6c2dcb801b)
Solutions
- Populate usage_info when building OCRResponse (pages_processed and/or credits).
- Fix the provider transformation to map the provider's usage fields into OCRUsageInfo.
- Retry/bill externally when the provider genuinely returns no usage data rather than forcing cost calc.
- Update LiteLLM for transformation fixes if the provider does return usage.
Example fix
# before ocr = OCRResponse(id=..., text=...) # usage_info omitted -> None # after from litellm.llms.base_llm.ocr.transformation import OCRUsageInfo ocr = OCRResponse(id=..., text=..., usage_info=OCRUsageInfo(pages_processed=2))
Defensive patterns
Strategy: type-guard
Validate before calling
if response.usage_info is None:
raise ValueError("OCR response missing usage_info; cannot price") Type guard
def ocr_usage_present(resp) -> bool:
return isinstance(resp, OCRResponse) and resp.usage_info is not None Try / catch
try:
cost = ocr_cost_fn(response=resp, model=model)
except ValueError as e:
if "usage_info is None" in str(e):
cost = 0.0 # bill externally; log the gap
else:
raise Prevention
- Always populate OCRUsageInfo in transformations, even with partial data.
- Log raw provider responses when usage is absent to identify schema changes.
- Add contract tests asserting usage_info is set after transformation.
When it happens
Trigger: Constructing OCRResponse without usage_info; an OCR provider call whose response lacks usage metadata; a transformation that maps usage fields only conditionally.
Common situations: Custom OCR integrations that skip usage mapping; providers that don't report pages processed; partially-implemented OCR transformations after upgrading LiteLLM.
Related errors
- OCR response pages_processed is None
- Model is None and does not exist in passed completion_respon
- usage object and custom_llm_provider must be provided for re
- response must be of type OCRResponse got type={type(response
- Invalid arg. Model cannot be none.
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/acc44e351a44b943.
Report an issue: GitHub.