{"record":{"id":"802c6ee2405e7beb","repo":"BerriAI/litellm","slug":"default-model-not-on-proxy-configure-via-model","errorCode":null,"errorMessage":"Default Model not on proxy. Configure via `/model/new` or config.yaml. Default_model={data.default_model}, proxy_model_names={set(llm_router.get_model_names())}","messagePattern":"Default Model not on proxy\\. Configure via `/model/new` or config\\.yaml\\. Default_model=(.+?), proxy_model_names=(.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":422,"severity":"error","filePath":"litellm/proxy/management_endpoints/customer_endpoints.py","lineNumber":419,"sourceCode":"        llm_router,\n        prisma_client,\n    )\n\n    if prisma_client is None:\n        raise HTTPException(\n            status_code=500,\n            detail={\"error\": CommonProxyErrors.db_not_connected_error.value},\n        )\n    try:\n        ## VALIDATION ##\n        if data.default_model is not None:\n            if llm_router is None:\n                raise HTTPException(\n                    status_code=422,\n                    detail={\"error\": CommonProxyErrors.no_llm_router.value},\n                )\n            elif data.default_model not in llm_router.get_model_names():\n                raise HTTPException(\n                    status_code=422,\n                    detail={\n                        \"error\": f\"Default Model not on proxy. Configure via `/model/new` or config.yaml. Default_model={data.default_model}, proxy_model_names={set(llm_router.get_model_names())}\"\n                    },\n                )\n\n        new_end_user_obj: dict[str, object] = {}\n\n        ## CREATE BUDGET ## if set\n        _new_budget: Final = new_budget_request(data)\n        if _new_budget is not None:\n            try:\n                budget_record: Final = await _typed_table(BudgetRepository(prisma_client)).create(\n                    data={\n                        **_new_budget.model_dump(exclude_unset=True),\n                        \"created_by\": user_api_key_dict.user_id or litellm_proxy_admin_name,\n                        \"updated_by\": user_api_key_dict.user_id or litellm_proxy_admin_name,\n                    }","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/customer_endpoints.py#L401-L437","documentation":"POST /customer/new rejects a default_model that is not among the router's model names (model_name entries in config.yaml model_list or models added via /model/new). The 422 detail echoes the requested default_model and the full proxy_model_names set, so the exact alias to use is visible in the error itself.","triggerScenarios":"Passing default_model \"gpt-4o\" when the proxy exposes it as \"openai/gpt-4o\" or an Azure deployment alias; typos; referencing a model that was removed from config while customer templates still name it.","commonSituations":"Teams migrating from the raw OpenAI SDK where provider ids worked directly; alias naming drift between environments (dev names openai/gpt-4o, prod names gpt4o-prod); retired deployments still referenced by onboarding scripts.","solutions":["Use an alias from the error's proxy_model_names set exactly as printed","Or add the model under the expected name: POST /model/new with model_name equal to the desired default_model","After creation, /customer/update can repoint default_model to an existing alias"],"exampleFix":"# before\ncurl -X POST http://localhost:4000/customer/new -d '{\"user_id\": \"u1\", \"default_model\": \"gpt-4o\"}'   # proxy only knows \"openai/gpt-4o\" -> 422\n\n# after\ncurl -X POST http://localhost:4000/customer/new -d '{\"user_id\": \"u1\", \"default_model\": \"openai/gpt-4o\"}'","handlingStrategy":"validation","validationCode":"import httpx\n\n\ndef model_exists(base: str, headers: dict, model: str) -> bool:\n    data = httpx.get(f\"{base}/v1/models\", headers=headers).json()[\"data\"]\n    return model in {m[\"id\"] for m in data}\n\n\nassert model_exists(BASE, HDR, payload[\"default_model\"]) or \"default_model\" not in payload","typeGuard":null,"tryCatchPattern":"try:\n    r = httpx.post(f\"{base}/customer/new\", json=payload, headers=headers)\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 422 and \"Default Model not on proxy\" in e.response.text:\n        # the detail lists valid proxy_model_names - pick one and retry\n        raise ValueError(f\"default_model invalid; pick from /v1/models\") from e\n    raise","preventionTips":["Derive default_model from GET /v1/models output instead of hardcoding provider ids","Keep model aliases consistent across environments via shared config or CI checks","When removing a model from config, grep customer/team configs for references first"],"tags":["litellm","model-alias","validation","customer-management","http-422"],"backgroundTag":"model-not-found","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}