BerriAI/litellm · error · Exception
Invalid arg. Model cannot be none.
Error message
Invalid arg. Model cannot be none.
What it means
The generic cost calculator (completion_cost) requires a model name to look up per-token pricing. If model is None — neither passed explicitly nor recoverable from the completion_response — it raises this generic Exception immediately, before reconstructing the usage block.
Source
Thrown at litellm/cost_calculator.py:353
Parameters:
model (str): The name of the model to use. Default is ""
prompt_tokens (int): The number of tokens in the prompt.
completion_tokens (int): The number of tokens in the completion.
response_time (float): The amount of time, in milliseconds, it took the call to complete.
prompt_characters (float): The number of characters in the prompt. Used for vertex ai cost calculation.
completion_characters (float): The number of characters in the completion response. Used for vertex ai cost calculation.
custom_llm_provider (str): The llm provider to whom the call was made (see init.py for full list)
custom_cost_per_token: Optional[CostPerToken]: the cost per input + output token for the llm api call.
custom_cost_per_second: Optional[float]: the cost per second for the llm api call.
call_type: Optional[str]: the call type
Returns:
tuple: A tuple containing the cost in USD dollars for prompt tokens and completion tokens, respectively.
"""
if model is None:
raise Exception("Invalid arg. Model cannot be none.")
## RECONSTRUCT USAGE BLOCK ##
if usage_object is not None:
usage_block = usage_object
else:
usage_block = Usage(
prompt_tokens=prompt_tokens,
completion_tokens=completion_tokens,
total_tokens=prompt_tokens + completion_tokens,
cache_creation_input_tokens=cache_creation_input_tokens,
cache_read_input_tokens=cache_read_input_tokens,
)
## CUSTOM PRICING ##
# Normalize cache token counts across providers:
# - OpenAI-compatible: usage.prompt_tokens_details.cached_tokens
# (prompt_tokens already INCLUDES cached_tokens)
# - Anthropic: usage.cache_read_input_tokens / cache_creation_input_tokensView on GitHub (pinned to 6c2dcb801b)
Solutions
- Pass model='provider/model-name' explicitly to completion_cost.
- Ensure the completion_response object includes a 'model' attribute — LiteLLM normally extracts it via completion_response.get('model').
- In tests, construct ModelResponse(..., model='gpt-4o-mini') or copy a real response shape.
- If wrapping LiteLLM, thread the original request's model through to the cost-calculation step.
Example fix
# before
cost = litellm.completion_cost(completion_response=mock_resp) # model missing
# after
cost = litellm.completion_cost(
completion_response=mock_resp,
model="gpt-4o-mini",
custom_llm_provider="openai",
) Defensive patterns
Strategy: validation
Validate before calling
if model is None:
model = completion_response.get("model") if completion_response else None
if model is None:
raise ValueError("model required for cost calculation") Type guard
def has_model_for_cost(model: str | None, resp) -> bool:
return model is not None or bool(resp and resp.get("model")) Try / catch
try:
cost = litellm.completion_cost(completion_response=resp, model=model)
except Exception as e:
if "Model cannot be none" in str(e):
cost = 0.0 # or re-raise with request context
else:
raise Prevention
- Always pass the request's model string explicitly to cost functions.
- Never build ModelResponse objects without setting the model field.
- In middleware, capture model at request start and reuse it for billing.
When it happens
Trigger: Calling litellm.completion_cost(model=None, completion_response=resp) where resp also lacks a 'model' field (custom ModelResponse, mocked responses, or stripped provider payloads); constructing ModelResponse manually and passing it to cost functions without setting .get('model').
Common situations: Unit tests with hand-built response objects; streaming code that builds a cost-call from a chunk that never carried the model; proxy handlers that drop the model field during serialization.
Related errors
- prompt_characters must be provided for tts calls. prompt_cha
- Model is None and does not exist in passed completion_respon
- soft_budget cannot be negative. Received: {data.soft_budget}
- soft_budget ({data.soft_budget}) must be strictly lower than
- Model '{m}' not in team's allowed models. Team allowed model
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/916b6da80d01ba59.
Report an issue: GitHub.