bytedance/deer-flow · error · HTTPException

NOT_AUTHENTICATED

NOT_AUTHENTICATED

Error message

Not authenticated

What it means

HTTP 401 with code NOT_AUTHENTICATED from get_current_user_from_request(). The function first trusts request.state.user set by AuthMiddleware (session, auth-disabled, or internal source); otherwise it reads the access_token cookie and raises this when the cookie is absent or empty. The response detail is an AuthErrorResponse payload, not a plain string.

Source

Thrown at backend/app/gateway/deps.py:755

    Raises HTTPException 401 if not authenticated.
    """
    state = getattr(request, "state", None)
    state_user = getattr(state, "user", None)
    from app.gateway.auth_disabled import AUTH_SOURCE_AUTH_DISABLED, AUTH_SOURCE_INTERNAL, AUTH_SOURCE_SESSION

    if state_user is not None and getattr(state, "auth_source", None) in {
        AUTH_SOURCE_SESSION,
        AUTH_SOURCE_AUTH_DISABLED,
        AUTH_SOURCE_INTERNAL,
    }:
        return state_user

    from app.gateway.auth import decode_token
    from app.gateway.auth.errors import AuthErrorCode, AuthErrorResponse, TokenError, token_error_to_code

    access_token = request.cookies.get("access_token")
    if not access_token:
        raise HTTPException(
            status_code=401,
            detail=AuthErrorResponse(code=AuthErrorCode.NOT_AUTHENTICATED, message="Not authenticated").model_dump(),
        )

    payload = decode_token(access_token)
    if isinstance(payload, TokenError):
        raise HTTPException(
            status_code=401,
            detail=AuthErrorResponse(code=token_error_to_code(payload), message=f"Token error: {payload.value}").model_dump(),
        )

    provider = get_local_provider()
    user = await provider.get_user(payload.sub)
    if user is None:
        raise HTTPException(
            status_code=401,
            detail=AuthErrorResponse(code=AuthErrorCode.USER_NOT_FOUND, message="User not found").model_dump(),
        )

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Log in via the auth flow to obtain a fresh access_token cookie, then retry with the cookie jar attached
  2. For fetch/XHR from a browser, send credentials: 'include' (same-origin via the nginx proxy usually works by default)
  3. If scripting, capture cookies from the login response (curl -c jar) and reuse them (curl -b jar)
  4. If you expected AuthMiddleware to have authenticated the request, verify auth is not failing earlier (session store down, auth disabled flag changed)

Example fix

// before (browser)
await fetch('/api/threads', { headers: { 'Authorization': 'Bearer xxx' } }); // 401 — auth is cookie-based
// after
await fetch('/api/threads', { credentials: 'include' });
Defensive patterns

Strategy: validation

Validate before calling

function hasSessionCookie(): boolean {
  return document.cookie.includes('access_token=');
}
if (!hasSessionCookie()) redirect('/login'); // before any authenticated fetch

Type guard

null

Try / catch

try:
    data = await api.get('/api/threads')
except HTTPError as e:
    if e.status === 401 && e.detail?.code === 'NOT_AUTHENTICATED':
        redirect('/login'); return;
    throw e;

Prevention

When it happens

Trigger: Any authenticated Gateway API call made without an access_token cookie and without AuthMiddleware having stamped request.state.user — e.g. curl without cookies, expired/cleared session, browser fetch from a different origin that excludes credentials, or calling before login.

Common situations: Session cookie expired and the client did not refresh it; front-end fetch missing credentials: 'include' when hitting the proxy from another origin; scripts that use an Authorization header (not supported here — auth is cookie-based); logout in another tab clearing the cookie.

Understand the failure class

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/3ced9e53f094a4db. Report an issue: GitHub.