BerriAI/litellm · error · ValueError
model param not passed in.
Error message
model param not passed in.
What it means
Plain ValueError raised as the very first validation step of completion(): the model argument is None. Everything downstream (provider routing, auth, params) derives from the model string, so litellm refuses immediately instead of guessing.
Source
Thrown at litellm/main.py:4996
api_key (str, optional): API key (default is None).
model_list (list, optional): List of api base, version, keys
extra_headers (dict, optional): Additional headers to include in the request.
LITELLM Specific Params
mock_response (str, optional): If provided, return a mock completion response for testing or debugging purposes (default is None).
custom_llm_provider (str, optional): Used for Non-OpenAI LLMs, Example usage for bedrock, set model="amazon.titan-tg1-large" and custom_llm_provider="bedrock"
max_retries (int, optional): The number of retries to attempt (default is 0).
Returns:
ModelResponse: A response object containing the generated completion and associated metadata.
Note:
- This function is used to perform completions() using the specified language model.
- It supports various optional parameters for customizing the completion behavior.
- If 'mock_response' is provided, a mock completion response is returned for testing or debugging.
"""
### VALIDATE Request ###
if model is None:
raise ValueError("model param not passed in.")
# validate messages
messages = validate_and_fix_openai_messages(messages=messages)
tools = validate_and_fix_openai_tools(tools=tools)
# validate tool_choice
tool_choice = validate_chat_completion_tool_choice(tool_choice=tool_choice)
# validate optional params
stop = validate_openai_optional_params(stop=stop)
# normalize camelCase thinking keys (e.g. budgetTokens -> budget_tokens)
thinking = validate_and_fix_thinking_param(thinking=thinking)
######### unpacking kwargs #####################
args: Final = _locals_snapshot(locals())
# Set by the responses->completion fallback so completion() does not bridge
# back to the Responses API: that round-trip mutually recurses forever for a
# model whose model_cost mode is "responses" but whose provider has no
# Responses API config (get_provider_responses_api_config -> None).
skip_responses_api_bridge: Final = kwargs.pop("_skip_responses_api_bridge", False)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Pass a concrete model string, e.g. 'gpt-4o' or 'azure/my-deploy'
- Find why the variable is None: print it / assert before the call -- usually a missing env var or config key
- Add a default at the source: model = os.environ.get('MODEL') or 'gpt-4o-mini'
- Guard the call site with a quick isinstance(model, str) and bool(model.strip()) check
Example fix
# before
model = os.environ.get('MODEL_NAME') # None when unset
resp = litellm.completion(model=model, messages=m) # ValueError: model param not passed in.
# after
model = os.environ.get('MODEL_NAME') or 'gpt-4o-mini'
resp = litellm.completion(model=model, messages=m) Defensive patterns
Strategy: type-guard
Validate before calling
model = os.environ.get('MODEL') or DEFAULT_MODEL
assert isinstance(model, str) and model.strip(), 'model must resolve to a non-empty string' Type guard
from typing import TypeGuard, Any
def is_model_name(value: Any) -> TypeGuard[str]:
return isinstance(value, str) and bool(value.strip()) Try / catch
try:
resp = litellm.completion(model=model, messages=m)
except ValueError as e:
if 'model param not passed in' in str(e):
raise RuntimeError('model resolution produced None; check config/env keys') from e
raise Prevention
- Never call completion with a possibly-None variable; default it first (os.environ.get('MODEL') or fallback)
- Validate config-driven model fields with a schema (pydantic) that requires a non-empty string
- Log the resolved model name at request start so None values are visible in traces
- Centralize model selection in one function and unit-test it returns a valid string for every config path
When it happens
Trigger: Calling litellm.completion(model=my_model, ...) where my_model is None -- typically a config key typo, an os.environ.get that returned None, or a dict lookup for the model name that missed.
Common situations: MODEL env var unset in one environment; config-driven model selection with a missing key; refactoring that renamed the variable holding the model but left the call with the old (empty) one; default argument chains ending in None.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- bucket_name must be provided for GCS destination
- max_budget cannot be negative. Received: {data.max_budget}
- 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@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/c2173f9ef35a40a0.
Report an issue: GitHub.