{"record":{"id":"77cbc31bf26dac27","repo":"bytedance/deer-flow","slug":"model-model-name-is-not-available-for-your-rol","errorCode":null,"errorMessage":"Model '{model_name}' is not available for your role","messagePattern":"Model '(.+?)' is not available for your role","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"backend/app/gateway/routers/models.py","lineNumber":180,"sourceCode":"            \"description\": \"OpenAI GPT-4 model\",\n            \"supports_thinking\": false\n        }\n        ```\n    \"\"\"\n    model = config.get_model_config(model_name)\n    if model is None:\n        raise HTTPException(status_code=404, detail=f\"Model '{model_name}' not found\")\n\n    # Phase 3: enforce model:use authorization (deny → 403, not 404, since the\n    # model exists but the role lacks permission to use it).\n    fail_closed = config.authorization.fail_closed\n    user = await get_optional_user_from_request(request)\n    if user is not None:\n        try:\n            provider, principal = resolve_model_authorization(user, is_internal=_is_internal_caller(request, user))\n        except _AuthorizationUnavailable:\n            if fail_closed:\n                raise HTTPException(status_code=403, detail=f\"Model '{model_name}' is not available for your role\")\n        else:\n            if provider is not None and principal is not None:\n                try:\n                    decision = provider.authorize(AuthzRequest(principal=principal, resource=\"model\", action=\"use\", target=model_name))\n                    if not isinstance(decision, AuthzDecision):\n                        raise TypeError(\"AuthorizationProvider.authorize must return AuthzDecision\")\n                    allowed = decision.allow\n                except Exception:\n                    logger.warning(\n                        \"Authorization provider failed while checking model:use for %s\",\n                        model_name,\n                        exc_info=True,\n                    )\n                    allowed = not fail_closed\n                if not allowed:\n                    raise HTTPException(status_code=403, detail=f\"Model '{model_name}' is not available for your role\")\n\n    return ModelResponse(","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/models.py#L162-L198","documentation":"Raised as HTTP 403 by GET /api/models/{model_name} when the authorization provider could not be reached/resolved (_AuthorizationUnavailable) and config.authorization.fail_closed is true. The model exists; access is denied because the system cannot confirm permission and is configured to deny on uncertainty.","triggerScenarios":"Requesting a valid model while the AuthorizationProvider is unregistered/misconfigured, and fail_closed: true is set in config.yaml. The provider lookup throws before any authorize() call.","commonSituations":"Enabling fail-closed authorization without wiring an auth provider; auth extension disabled but authorization config still active; internal auth service dependency down at startup.","solutions":["Fix or register the AuthorizationProvider so resolve_model_authorization succeeds (check gateway startup logs for provider load errors).","If the deployment intentionally has no authorization, set authorization.fail_closed: false (or disable the authorization block) in config.yaml and restart the Gateway.","If fail-closed is intended, restore the auth backend the provider depends on."],"exampleFix":"# config.yaml — before\nauthorization:\n  fail_closed: true   # provider unavailable -> 403\n# after (no auth provider deployed)\nauthorization:\n  fail_closed: false","handlingStrategy":"fallback","validationCode":"# preflight: does the gateway resolve authorization for this token?\nme = requests.get(f\"{BASE}/api/me\", headers=auth)  # or any authed endpoint\nassert me.status_code != 403, \"authz stack unavailable; fail_closed will deny model access\"","typeGuard":null,"tryCatchPattern":"resp = requests.get(f\"{BASE}/api/models/{model_name}\", headers=auth)\nif resp.status_code == 403:\n    detail = resp.json()[\"detail\"]\n    if \"not available for your role\" in detail:\n        # distinguish infra failure from policy deny via gateway logs,\n        # then fall back to a known-allowed default model\n        switch_to_default_model()","preventionTips":["Do not enable fail_closed until an AuthorizationProvider is verified to load at startup.","Watch gateway logs for 'Authorization provider failed' warnings — they precede this 403 when fail_closed.","Smoke-test one model request after any authorization config change."],"tags":["authorization","models","http-403","fail-closed","config"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}