{"record":{"id":"1352988a32859d02","repo":"BerriAI/litellm","slug":"invalid-provider-s-join-invalid-providers","errorCode":null,"errorMessage":"Invalid provider(s): {', '.join(invalid_providers)}. Must be valid LiteLLM providers. See https://docs.litellm.ai/docs/providers for the full list.","messagePattern":"Invalid provider\\(s\\): (.+?)\\. Must be valid LiteLLM providers\\. See https://docs\\.litellm\\.ai/docs/providers for the full list\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"litellm/proxy/management_endpoints/cost_tracking_settings.py","lineNumber":219,"sourceCode":"        raise HTTPException(\n            status_code=500,\n            detail={\"error\": CommonProxyErrors.db_not_connected_error.value},\n        )\n\n    if store_model_in_db is not True:\n        raise HTTPException(\n            status_code=500,\n            detail={\"error\": \"Set `'STORE_MODEL_IN_DB='True'` in your env to enable this feature.\"},\n        )\n\n    # Validate that all providers are valid LiteLLM providers\n    invalid_providers: Final = []\n    for provider in cost_discount_config:\n        if provider not in LlmProvidersSet:\n            invalid_providers.append(provider)\n\n    if invalid_providers:\n        raise HTTPException(\n            status_code=400,\n            detail={\n                \"error\": f\"Invalid provider(s): {', '.join(invalid_providers)}. Must be valid LiteLLM providers. See https://docs.litellm.ai/docs/providers for the full list.\"\n            },\n        )\n\n    # Validate discount values are between 0 and 1\n    for provider, discount in cost_discount_config.items():\n        if not isinstance(discount, (int, float)):\n            raise HTTPException(status_code=400, detail=f\"Discount for {provider} must be a number\")\n        if not (0 <= discount <= 1):\n            raise HTTPException(\n                status_code=400,\n                detail=f\"Discount for {provider} must be between 0 and 1 (0% to 100%)\",\n            )\n\n    try:\n        # Load existing config","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/cost_tracking_settings.py#L201-L237","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\n{\"error\": ...}\ncurl -X PATCH .../config/cost_discount_config -d '{\"gpt-4o\": 0.10}'\n# 400 Invalid provider(s): gpt-4o\n\n# after\ncurl -X PATCH .../config/cost_discount_config -d '{\"openai\": 0.10}'","handlingStrategy":"validation","validationCode":"from litellm.constants import PROVIDERS  # or: import litellm; set(litellm.provider_list)\nLLM_PROVIDERS = set(litellm.provider_list)  # canonical provider slugs\n\nbad = [k for k in cost_discount_config if k not in LLM_PROVIDERS]\nif bad:\n    raise ValueError(f\"Not LiteLLM providers: {bad}\")","typeGuard":"def is_valid_discount_config(cfg: dict) -> bool:\n    return (\n        isinstance(cfg, dict)\n        and all(isinstance(k, str) and k in set(litellm.provider_list) for k in cfg)\n        and all(isinstance(v, (int, float)) and not isinstance(v, bool) and 0 <= v <= 1 for v in cfg.values())\n    )","tryCatchPattern":"try:\n    r = requests.patch(f\"{PROXY_URL}/config/cost_discount_config\", json=payload, headers=HDRS)\n    r.raise_for_status()\nexcept requests.HTTPError as e:\n    if e.response.status_code == 400 and \"Invalid provider\" in e.response.text:\n        # surface the offending keys from the message and fix the mapping\n        handle_invalid_providers(e.response.json())\n    else:\n        raise","preventionTips":["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."],"tags":["litellm-proxy","validation","cost-tracking","providers"],"backgroundTag":"schema-validation-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}