BerriAI/litellm · error · ValueError
Exactly one of model_id or model_name must be provided
Error message
Exactly one of model_id or model_name must be provided
What it means
Client-side guard inside ModelsManagementClient.get(): the method requires exactly one of model_id / model_name, and passing neither or both raises ValueError('Exactly one of model_id or model_name must be provided') before any network call. get() then downloads the full /v1/model/info list and filters locally by the single identifier you gave, which is why the arguments are mutually exclusive. This is a pure programming error in the caller, not a server condition.
Source
Thrown at litellm/proxy/client/models.py:178
Get information about a specific model by its ID or name.
Args:
model_id (Optional[str]): ID of the model to retrieve
model_name (Optional[str]): Name of the model to retrieve
return_request (bool): If True, returns the prepared request object instead of executing it
Returns:
Union[Dict[str, Any], requests.Request]: Either the model information from the server or
a prepared request object if return_request is True
Raises:
ValueError: If neither model_id nor model_name is provided, or if both are provided
UnauthorizedError: If the request fails with a 401 status code
NotFoundError: If the model is not found
requests.exceptions.RequestException: If the request fails with any other error
"""
if (model_id is None and model_name is None) or (model_id is not None and model_name is not None):
raise ValueError("Exactly one of model_id or model_name must be provided")
# If return_request is True, delegate to info
if return_request:
result: Final = self.info(return_request=True)
assert isinstance(result, requests.Request)
return result
# Get all models and filter
models: Final = self.info()
assert isinstance(models, list)
# Find the matching model
for model in models:
if (model_id and model.get("model_info", {}).get("id") == model_id) or (
model_name and model.get("model_name") == model_name
):
return model
View on GitHub (pinned to 77b7c6c40c)
Solutions
- Pass exactly one identifier: models.get(model_id='2f23364f-...') or models.get(model_name='gpt-4o-mini')
- Normalize optional kwargs to None (and drop them) before calling so the guard sees exactly one
- If you somehow hold both, prefer model_id — UUIDs are exact matches, names can collide
Example fix
# before
model = client.models.get(model_id=None, model_name=None) # ValueError
# after
model = (
client.models.get(model_id=model_id)
if model_id is not None
else client.models.get(model_name=model_name)
) Defensive patterns
Strategy: validation
Validate before calling
def get_model_kwargs(model_id: str | None, model_name: str | None) -> dict:
if (model_id is None) == (model_name is None):
raise ValueError("pass exactly one of model_id / model_name")
return {"model_id": model_id} if model_id is not None else {"model_name": model_name}
# models.get(**get_model_kwargs(model_id, model_name)) Type guard
from typing import Any
def is_valid_get_args(model_id: Any, model_name: Any) -> bool:
return (model_id is None) != (model_name is None) # exactly one set Try / catch
try:
model = models.get(model_id=model_id, model_name=model_name)
except ValueError as e:
if "Exactly one" in str(e):
model = models.get(**get_model_kwargs(model_id, model_name)) # normalize and retry
else:
raise Prevention
- Normalize optional identifiers to None and drop empty strings before calling get()
- Wrap the call with a one-argument helper so the invariant is enforced in one place
- Remember get() filters locally over /v1/model/info — an empty-string id won't raise here but will 404-match nothing
When it happens
Trigger: Calling get() with no arguments; calling get(model_id=_id, model_name=name) when both variables are populated; forwarding optional kwargs from your own wrapper into get() without normalizing absent values to None; refactor renaming one parameter so callers accidentally set both.
Common situations: Wrapper APIs that accept optional model_id and model_name and pass them straight through; dynamic callers building kwargs dicts that end up empty; copy-pasted calls carrying leftover arguments.
Related errors
- Model with id={model_id} not found
- {e}
- 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
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/935e77d26f991ac4.
Report an issue: GitHub.