BerriAI/litellm · error · ValueError
custom_llm_provider is required for Anthropic messages, pass
Error message
custom_llm_provider is required for Anthropic messages, passed in model={model}, custom_llm_provider={custom_llm_provider} What it means
Raised in the Anthropic messages handler when the requested model can be routed by the litellm proxy (e.g. via model_list) but no custom_llm_provider could be resolved, and the model is not one of the known model-info paths that infer the provider. litellm needs custom_llm_provider to pick the correct provider transformation, so a None value after all resolution attempts is fatal.
Source
Thrown at litellm/llms/anthropic/experimental_pass_through/messages/handler.py:566
api_key=api_key,
api_base=api_base,
client=client,
custom_llm_provider=custom_llm_provider,
**kwargs,
)
if _should_route_to_responses_api(custom_llm_provider):
return LiteLLMMessagesToResponsesAPIHandler.anthropic_messages_handler(**_shared_kwargs)
# The in-gateway context_management polyfill runs inside
# ``async_anthropic_messages_handler`` so it can ``await`` the
# summarization model for ``compact_20260112``. ``context_management``
# is passed through as a regular kwarg.
return LiteLLMMessagesToCompletionTransformationHandler.anthropic_messages_handler(
**_shared_kwargs,
)
if custom_llm_provider is None:
raise ValueError(
f"custom_llm_provider is required for Anthropic messages, passed in model={model}, custom_llm_provider={custom_llm_provider}"
)
local_vars.update(kwargs)
anthropic_messages_optional_request_params: Final = (
AnthropicMessagesRequestUtils.get_requested_anthropic_messages_optional_param(
params=local_vars,
model=model,
drop_params=litellm_params.get("drop_params") is True,
custom_llm_provider=custom_llm_provider,
)
)
if is_reasoning_auto_summary_enabled():
thinking_param: Final = anthropic_messages_optional_request_params.get("thinking")
if isinstance(thinking_param, dict) and thinking_param.get("type") != "disabled":
anthropic_messages_optional_request_params["thinking"] = {
**thinking_param,
"display": "summarized",View on GitHub (pinned to 6c2dcb801b)
Solutions
- Prefix the model with the provider: model='anthropic/claude-3-5-sonnet-20241022'.
- Or pass custom_llm_provider='anthropic' explicitly to the handler call.
- If running through the proxy, ensure the model is present in litellm.model_list / model_info so provider resolution succeeds.
Example fix
# before response = litellm.anthropic_messages(model="claude-3-5-sonnet", messages=..., max_tokens=100) # after response = litellm.anthropic_messages(model="anthropic/claude-3-5-sonnet-20241022", messages=..., max_tokens=100)
Defensive patterns
Strategy: validation
Validate before calling
def resolve_model_spec(model: str, custom_llm_provider: str | None) -> tuple[str, str]:
if custom_llm_provider:
return model, custom_llm_provider
if "/" in model:
return model.split("/", 1)[1], model.split("/", 1)[0]
raise ValueError(f"model {model!r} needs a provider prefix (e.g. 'anthropic/...') or custom_llm_provider") Type guard
def model_has_resolvable_provider(model: str, custom_llm_provider: str | None = None) -> bool:
return bool(custom_llm_provider) or (isinstance(model, str) and "/" in model) Try / catch
try:
resp = litellm.anthropic_messages(model=model, ...)
except ValueError as e:
if "custom_llm_provider is required" in str(e):
resp = litellm.anthropic_messages(model=f"anthropic/{model}", ...)
else:
raise Prevention
- Always use the 'provider/model' form for direct SDK calls outside the proxy.
- When wrapping the API, default custom_llm_provider based on your deployment.
- Register custom models in proxy model_list so provider inference succeeds.
When it happens
Trigger: Calling anthropic_messages-style completion with model='claude-3-5-sonnet' (no 'anthropic/' prefix) outside a proxy deployment where model_info lookups succeed, and without passing custom_llm_provider='anthropic'. Also with custom model names that litellm cannot map to a provider.
Common situations: Using the SDK directly (not via the proxy) with a bare model name; custom_llm_provider passed as None explicitly by wrapper code; deployments where the model is not in the router's model_list so provider inference fails.
Related errors
- Missing Azure API Base - Please set `api_base` or `AZURE_API
- Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassi
- Error: {response.status_code} - {response.text}
- Missing Authorization header
- Invalid bearer token
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/5728e3fa97df282c.
Report an issue: GitHub.