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 or 'global'. See https://docs.litellm.ai/docs/providers for the full list. What it means
Validation error (HTTP 400) from PATCH /config/cost_margin_config: every key must be either the reserved key 'global' or a valid LiteLLM provider (member of LlmProvidersSet). Unrecognized keys are collected and reported in one comma-joined message. Note this endpoint — unlike the discount one — allows the special 'global' key.
Source
Thrown at litellm/proxy/management_endpoints/cost_tracking_settings.py:357
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 (except "global")
invalid_providers: Final = []
for provider in cost_margin_config:
if provider != "global" and 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 or 'global'. See https://docs.litellm.ai/docs/providers for the full list."
},
)
# Validate margin values
for provider, margin_value in cost_margin_config.items():
if isinstance(margin_value, (int, float)):
# Simple percentage format: {"openai": 0.10}
if not (0 <= margin_value <= 10): # Allow up to 1000% margin
raise HTTPException(
status_code=400,
detail=f"Margin percentage for {provider} must be between 0 and 10 (0% to 1000%)",
)
elif isinstance(margin_value, dict):
# Complex format: {"percentage": 0.08, "fixed_amount": 0.0005}
if "percentage" in margin_value:View on GitHub (pinned to 77b7c6c40c)
Solutions
- Use canonical LiteLLM provider slugs ('openai', 'anthropic', 'vertex_ai', 'bedrock', ...) or 'global' for a catch-all margin.
- Check spelling against https://docs.litellm.ai/docs/providers or litellm.provider_list.
- For per-model margins, set pricing/margins on the deployment's model_info instead.
Example fix
# before
{"vertex": 0.08} # 400 Invalid provider(s): vertex
# after
{"vertex_ai": 0.08} # or {"global": 0.08} Defensive patterns
Strategy: validation
Validate before calling
import litellm
VALID_KEYS = set(litellm.provider_list) | {"global"}
bad = [k for k in cost_margin_config if k not in VALID_KEYS]
if bad:
raise ValueError(f"Keys must be LiteLLM providers or 'global', got: {bad}") Type guard
def is_valid_margin_keys(cfg: dict) -> bool:
valid = set(litellm.provider_list) | {"global"}
return all(k in valid for k in cfg) Prevention
- Remember 'global' is valid only for margins, not discounts.
- Use exact slugs like 'vertex_ai' and 'bedrock'.
- Validate keys in CI against litellm.provider_list.
When it happens
Trigger: Sending model names as keys ({"gpt-4": 0.1}), provider typos ("vertex" instead of "vertex_ai"), or a misplaced 'default' key instead of 'global'.
Common situations: Assuming margin keys mirror the discount endpoint exactly; using vendor console names ('Google', 'AWS') rather than LiteLLM provider slugs.
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/36adfc4098912da3.
Report an issue: GitHub.