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 config

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Use only canonical LiteLLM provider names as keys, e.g. {"openai": 0.01, "azure": 0.05}.
  2. Check https://docs.litellm.ai/docs/providers (or litellm.provider_list) for the exact spelling of the provider you want.
  3. 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

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


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/1352988a32859d02. Report an issue: GitHub.