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

  1. Use canonical LiteLLM provider slugs ('openai', 'anthropic', 'vertex_ai', 'bedrock', ...) or 'global' for a catch-all margin.
  2. Check spelling against https://docs.litellm.ai/docs/providers or litellm.provider_list.
  3. 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

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


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