{"record":{"id":"916b6da80d01ba59","repo":"BerriAI/litellm","slug":"invalid-arg-model-cannot-be-none","errorCode":null,"errorMessage":"Invalid arg. Model cannot be none.","messagePattern":"Invalid arg\\. Model cannot be none\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/cost_calculator.py","lineNumber":353,"sourceCode":"\n    Parameters:\n        model (str): The name of the model to use. Default is \"\"\n        prompt_tokens (int): The number of tokens in the prompt.\n        completion_tokens (int): The number of tokens in the completion.\n        response_time (float): The amount of time, in milliseconds, it took the call to complete.\n        prompt_characters (float): The number of characters in the prompt. Used for vertex ai cost calculation.\n        completion_characters (float): The number of characters in the completion response. Used for vertex ai cost calculation.\n        custom_llm_provider (str): The llm provider to whom the call was made (see init.py for full list)\n        custom_cost_per_token: Optional[CostPerToken]: the cost per input + output token for the llm api call.\n        custom_cost_per_second: Optional[float]: the cost per second for the llm api call.\n        call_type: Optional[str]: the call type\n\n    Returns:\n        tuple: A tuple containing the cost in USD dollars for prompt tokens and completion tokens, respectively.\n    \"\"\"\n\n    if model is None:\n        raise Exception(\"Invalid arg. Model cannot be none.\")\n\n    ## RECONSTRUCT USAGE BLOCK ##\n    if usage_object is not None:\n        usage_block = usage_object\n    else:\n        usage_block = Usage(\n            prompt_tokens=prompt_tokens,\n            completion_tokens=completion_tokens,\n            total_tokens=prompt_tokens + completion_tokens,\n            cache_creation_input_tokens=cache_creation_input_tokens,\n            cache_read_input_tokens=cache_read_input_tokens,\n        )\n\n    ## CUSTOM PRICING ##\n    # Normalize cache token counts across providers:\n    #   - OpenAI-compatible: usage.prompt_tokens_details.cached_tokens\n    #     (prompt_tokens already INCLUDES cached_tokens)\n    #   - Anthropic: usage.cache_read_input_tokens / cache_creation_input_tokens","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/cost_calculator.py#L335-L371","documentation":"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.","triggerScenarios":"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').","commonSituations":"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.","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."],"exampleFix":"# before\ncost = litellm.completion_cost(completion_response=mock_resp)  # model missing\n\n# after\ncost = litellm.completion_cost(\n    completion_response=mock_resp,\n    model=\"gpt-4o-mini\",\n    custom_llm_provider=\"openai\",\n)","handlingStrategy":"validation","validationCode":"if model is None:\n    model = completion_response.get(\"model\") if completion_response else None\nif model is None:\n    raise ValueError(\"model required for cost calculation\")","typeGuard":"def has_model_for_cost(model: str | None, resp) -> bool:\n    return model is not None or bool(resp and resp.get(\"model\"))","tryCatchPattern":"try:\n    cost = litellm.completion_cost(completion_response=resp, model=model)\nexcept Exception as e:\n    if \"Model cannot be none\" in str(e):\n        cost = 0.0  # or re-raise with request context\n    else:\n        raise","preventionTips":["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."],"tags":["litellm","cost-calculation","validation","model-name"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}