bytedance/deer-flow · error · HTTPException

Authentication required

Error message

Authentication required

What it means

401 Unauthorized from the channel-connections router's helper _get_user_id (channel_connections.py:142): request.state.user is None, meaning no authenticated user was resolved for the request. The channel connection API is user-scoped (every connection binds to an owner), so an anonymous request cannot proceed. It typically indicates the auth middleware did not run/populate state — the route's normal auth dependency should have rejected the request earlier.

Source

Thrown at backend/app/gateway/routers/channel_connections.py:142

    ),
}

_RUNTIME_REQUIREMENTS: dict[str, tuple[str, ...]] = {
    "telegram": ("bot_token",),
    "slack": ("bot_token", "app_token"),
    "discord": ("bot_token",),
    "feishu": ("app_id", "app_secret"),
    "dingtalk": ("client_id", "client_secret"),
    "wechat": ("bot_token",),
    "wecom": ("bot_id", "bot_secret"),
    "buzz": ("relay_url", "private_key"),
}


def _get_user_id(request: Request) -> str:
    user = getattr(request.state, "user", None)
    if user is None:
        raise HTTPException(status_code=401, detail="Authentication required")
    return str(user.id)


def _get_app_config():
    from deerflow.config.app_config import get_app_config

    return get_app_config()


async def _get_runtime_config_store(request: Request) -> ChannelRuntimeConfigStore:
    store = getattr(request.app.state, "channel_runtime_config_store", None)
    if isinstance(store, ChannelRuntimeConfigStore):
        return store
    # Constructing the store reads its JSON file from disk; keep it off the
    # event loop.
    store = await asyncio.to_thread(ChannelRuntimeConfigStore)
    request.app.state.channel_runtime_config_store = store
    return store

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Authenticate first: obtain a session (login) or valid token and send it with the request (cookie or Authorization header, per the Gateway auth scheme)
  2. If this appears in tests, ensure the test client sets up request.state.user or uses the app's auth fixtures rather than hitting the router function bare
  3. Verify the channel-connections router is mounted with its auth dependency intact (not include_router(..., dependencies=[]) overrides)

Example fix

# before
curl -X GET http://localhost:2026/api/channels/connections
# -> 401 Authentication required

# after
TOKEN=$(curl -s -X POST http://localhost:2026/api/auth/login -d 'username=...&password=...' | jq -r .access_token)
curl -H "Authorization: Bearer $TOKEN" http://localhost:2026/api/channels/connections
Defensive patterns

Strategy: validation

Validate before calling

const resp = await fetch("/api/channels/connections");
if (resp.status === 401) { await redirectToLogin(); return; }
const data = await resp.json();

Try / catch

try { await listConnections() } catch (e) { if (e.status === 401) { await reauthenticate(); retryOnce(); } else throw e; }

Prevention

When it happens

Trigger: Calling /api/channels/connections/* endpoints without a valid session/JWT (or with an expired token) in a context where the router-level auth dependency was bypassed — e.g. direct internal invocation, misconfigured middleware ordering, or a token that failed cookie/bearer resolution.

Common situations: Scripting the channel-connection endpoints with a missing/expired access token; auth disabled mode where routes are mounted but state.user is never set; middleware chain reordered so channel routes mount before auth wiring.

Understand the failure class

Related errors


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