bytedance/deer-flow · error · HTTPException
{detail}
Error message
{detail} What it means
HTTP 403 raised by require_admin_user() when the authenticated caller's system_role is not 'admin'. The dependency first prefers request.state.user stamped by AuthMiddleware, falling back to get_current_user_from_request(); the detail string is supplied per-route by the caller, so the message varies by endpoint.
Source
Thrown at backend/app/gateway/deps.py:804
"""Require the authenticated caller to be an admin user.
``AuthMiddleware`` normally stamps ``request.state.user`` before the request
reaches a router. Falling back to the strict dependency keeps the route safe
in tests or alternative ASGI compositions that mount a router without the
global middleware. ``detail`` is the route-specific 403 message.
Centralising this here means a future change to the admin definition (e.g.
allowing an internal system role, adding audit logging, or switching to a
permission-based check) lands in one place instead of drifting across the
per-router copies that previously existed in ``mcp``, ``channel_connections``
and ``channels``.
"""
user = getattr(request.state, "user", None)
if user is None:
user = await get_current_user_from_request(request)
if getattr(user, "system_role", None) != "admin":
raise HTTPException(status_code=403, detail=detail)
async def get_optional_user_from_request(request: Request):
"""Get optional authenticated user from request.
Returns None if not authenticated.
"""
try:
return await get_current_user_from_request(request)
except HTTPException:
return None
async def get_current_user(request: Request) -> str | None:
"""Extract user_id from request cookie, or None if not authenticated.
Thin adapter that returns the string id for callers that only need
identification (e.g., ``feedback.py``). Full-user callers should useView on GitHub (pinned to 1dd6ba1acb)
Solutions
- Verify the caller's system_role in the users store; promote the intended account (UPDATE users SET system_role='admin' or the admin management endpoint)
- Log in as an actual admin user for admin operations
- If the request should have been stamped by AuthMiddleware with an internal admin identity, confirm the middleware ordering and that the internal auth source is enabled for that path
- In tests, use the admin user fixture
Defensive patterns
Strategy: validation
Validate before calling
// before calling admin APIs
const me = await api.get('/api/auth/me');
if (me.system_role !== 'admin') throw new Error('admin only'); Type guard
type IsAdmin = (u: { system_role?: string } | null) => boolean;
const isAdmin: IsAdmin = (u) => u?.system_role === 'admin'; Try / catch
try {
await api.post('/api/admin/extensions/enable', body)
except HTTPError as e:
if e.status == 403:
raise PermissionError('Admin role required for this operation')
raise Prevention
- Hide admin UI affordances unless system_role === 'admin'
- Seed the first admin account explicitly during provisioning
- Return the caller's role from /me so clients can gate without guessing
When it happens
Trigger: Calling an admin-only route (extension management in mcp/channels/channel_connections routers, admin config endpoints) as a regular user or with a token whose user record lacks system_role='admin'.
Common situations: Default first-registered user is not admin and tries admin endpoints; user record edited/seeded without the admin role; internal/system service account (not an admin user) hitting an admin route; tests using a standard user fixture for admin flows.
Related errors
- Permission denied: {resource}:{action}
- Your email could not be verified by the identity provider. P
- The identity provider did not provide an email address.
- Your email domain is not allowed. Please use an approved ema
- Automatic account creation is disabled. Contact your adminis
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/77e8da38befa28ab.
Report an issue: GitHub.