BerriAI/litellm · warning · HTTPException
Invalid provider(s): {', '.join(invalid_providers)}. Must be
Error message
Invalid provider(s): {', '.join(invalid_providers)}. Must be valid LiteLLM providers. See https://docs.litellm.ai/docs/providers for the full list. What it means
Validation error (HTTP 400) from PATCH /config/cost_discount_config: every key of the cost_discount_config payload must be a known LiteLLM provider literal (member of LlmProvidersSet, e.g. 'openai', 'anthropic', 'gemini'). Keys that are not recognized providers are collected and reported together in one comma-joined message.
Source
Thrown at litellm/proxy/management_endpoints/cost_tracking_settings.py:219
raise HTTPException(
status_code=500,
detail={"error": CommonProxyErrors.db_not_connected_error.value},
)
if store_model_in_db is not True:
raise HTTPException(
status_code=500,
detail={"error": "Set `'STORE_MODEL_IN_DB='True'` in your env to enable this feature."},
)
# Validate that all providers are valid LiteLLM providers
invalid_providers: Final = []
for provider in cost_discount_config:
if provider not in LlmProvidersSet:
invalid_providers.append(provider)
if invalid_providers:
raise HTTPException(
status_code=400,
detail={
"error": f"Invalid provider(s): {', '.join(invalid_providers)}. Must be valid LiteLLM providers. See https://docs.litellm.ai/docs/providers for the full list."
},
)
# Validate discount values are between 0 and 1
for provider, discount in cost_discount_config.items():
if not isinstance(discount, (int, float)):
raise HTTPException(status_code=400, detail=f"Discount for {provider} must be a number")
if not (0 <= discount <= 1):
raise HTTPException(
status_code=400,
detail=f"Discount for {provider} must be between 0 and 1 (0% to 100%)",
)
try:
# Load existing configView on GitHub (pinned to 77b7c6c40c)
Solutions
- Use only canonical LiteLLM provider names as keys, e.g. {"openai": 0.01, "azure": 0.05}.
- Check https://docs.litellm.ai/docs/providers (or litellm.provider_list) for the exact spelling of the provider you want.
- For per-model discounts, use the model-level pricing/discount mechanisms (e.g. model_info pricing in the config) instead of this endpoint.
Example fix
# before
{"error": ...}
curl -X PATCH .../config/cost_discount_config -d '{"gpt-4o": 0.10}'
# 400 Invalid provider(s): gpt-4o
# after
curl -X PATCH .../config/cost_discount_config -d '{"openai": 0.10}' Defensive patterns
Strategy: validation
Validate before calling
from litellm.constants import PROVIDERS # or: import litellm; set(litellm.provider_list)
LLM_PROVIDERS = set(litellm.provider_list) # canonical provider slugs
bad = [k for k in cost_discount_config if k not in LLM_PROVIDERS]
if bad:
raise ValueError(f"Not LiteLLM providers: {bad}") Type guard
def is_valid_discount_config(cfg: dict) -> bool:
return (
isinstance(cfg, dict)
and all(isinstance(k, str) and k in set(litellm.provider_list) for k in cfg)
and all(isinstance(v, (int, float)) and not isinstance(v, bool) and 0 <= v <= 1 for v in cfg.values())
) Try / catch
try:
r = requests.patch(f"{PROXY_URL}/config/cost_discount_config", json=payload, headers=HDRS)
r.raise_for_status()
except requests.HTTPError as e:
if e.response.status_code == 400 and "Invalid provider" in e.response.text:
# surface the offending keys from the message and fix the mapping
handle_invalid_providers(e.response.json())
else:
raise Prevention
- Keep a curated allowlist of provider slugs in your config tooling.
- Never send model names where provider names are expected.
- Validate keys against litellm.provider_list in CI for config PRs.
When it happens
Trigger: Sending a payload like {"gpt-4": 0.1} (a model name, not a provider), typos like "antropic" or "open AI", or vendor aliases that are not LiteLLM provider enums.
Common situations: Confusing model-level discounts with provider-level discounts (this API only supports providers); copy-pasting provider names from another tool's naming scheme; trailing whitespace or case differences in provider keys.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid provider(s): {', '.join(invalid_providers)}. Must be
- Discount for {provider} must be a number
- Discount for {provider} must be between 0 and 1 (0% to 100%)
- Margin percentage for {provider} must be between 0 and 10 (0
- Margin percentage for {provider} must be a number
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/1352988a32859d02.
Report an issue: GitHub.