bytedance/deer-flow · warning · HTTPException
Model '{model_name}' not found
Error message
Model '{model_name}' not found What it means
Raised as HTTP 404 by GET /api/models/{model_name} when config.get_model_config(model_name) returns None — the requested model name is not present in the resolved configuration's model list. Authorization is checked only after existence, so this fires before any role-based filtering.
Source
Thrown at backend/app/gateway/routers/models.py:169
Raises:
HTTPException: 404 if model not found; 403 if the caller's role may not
``use`` the model (only when ``authorization.enabled`` is true). A
provider resolution error yields 403 (fail-closed) or allows the request
(fail-open), mirroring ``list_models``'s provider-error semantics.
Example Response:
```json
{
"name": "gpt-4",
"display_name": "GPT-4",
"description": "OpenAI GPT-4 model",
"supports_thinking": false
}
```
"""
model = config.get_model_config(model_name)
if model is None:
raise HTTPException(status_code=404, detail=f"Model '{model_name}' not found")
# Phase 3: enforce model:use authorization (deny → 403, not 404, since the
# model exists but the role lacks permission to use it).
fail_closed = config.authorization.fail_closed
user = await get_optional_user_from_request(request)
if user is not None:
try:
provider, principal = resolve_model_authorization(user, is_internal=_is_internal_caller(request, user))
except _AuthorizationUnavailable:
if fail_closed:
raise HTTPException(status_code=403, detail=f"Model '{model_name}' is not available for your role")
else:
if provider is not None and principal is not None:
try:
decision = provider.authorize(AuthzRequest(principal=principal, resource="model", action="use", target=model_name))
if not isinstance(decision, AuthzDecision):
raise TypeError("AuthorizationProvider.authorize must return AuthzDecision")
allowed = decision.allowView on GitHub (pinned to 1dd6ba1acb)
Solutions
- Call GET /api/models to list configured model names and use one of those exactly.
- Add or fix the model entry under the models section of config.yaml at the repo root, then reload config.
- If you expected the model to exist, diff config.yaml against config.example.yaml for renames or missing entries.
Example fix
# config.yaml — before: model key is "gpt-4o"
models:
gpt-4o:
... # GET /api/models/gpt4 -> 404
# after: request the exact key
models:
gpt-4o:
...
# GET /api/models/gpt-4o -> 200 Defensive patterns
Strategy: validation
Validate before calling
models = requests.get(f"{BASE}/api/models").json()
valid_names = {m["name"] for m in models}
assert model_name in valid_names, f"{model_name} not configured; valid: {sorted(valid_names)}" Type guard
def is_configured_model(name: str, catalog: list[dict]) -> bool:
return any(m.get("name") == name for m in catalog) Try / catch
resp = requests.get(f"{BASE}/api/models/{model_name}")
if resp.status_code == 404:
model_name = pick_from_listed_models() # recover by re-selecting
else:
resp.raise_for_status() Prevention
- Populate model pickers from GET /api/models, never hardcode names.
- Keep config.yaml's models section in sync when renaming or removing entries.
- Run make doctor after config edits to catch schema/name mistakes.
When it happens
Trigger: GET /api/models/{model_name} with a name absent from config.yaml's models section: typo ('gpt4' vs 'gpt-4'), model removed from config, or config.yaml not yet populated from config.example.yaml.
Common situations: Frontend or script hardcodes a model name that the deployment's config.yaml does not define; after upgrading, model keys renamed; default config copied but models left as examples.
Related errors
- Unknown model '{model}'. Use a model name defined under `mod
- SSO authentication is not enabled
- Browser automation is not enabled
- MCP server '{body.server_name}' not found
- Model '{model_name}' is not available for your role
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/391c7f6f74834666.
Report an issue: GitHub.