agentscope-ai/agentscope · error · HTTPException

X-User-ID header is required.

Error message

X-User-ID header is required.

What it means

HTTPException 401 raised by the get_current_user_id FastAPI dependency when the X-User-ID request header is absent or empty. This lightweight auth scheme identifies users purely by that header, so a missing header means the request is unauthenticated and every endpoint using the dependency rejects it.

Source

Thrown at src/agentscope/app/deps.py:50

async def get_current_user_id(
    x_user_id: str = Header(
        description="Caller's user ID. "
        "Temporary header-based identity; will be replaced by JWT auth.",
    ),
) -> str:
    """Return the caller's user ID from the ``X-User-ID`` request header.

    Args:
        x_user_id (`str`): Value of the ``X-User-ID`` header.

    Returns:
        `str`: The authenticated user ID.

    Raises:
        `HTTPException`: 401 if the header is missing or empty.
    """
    if not x_user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="X-User-ID header is required.",
        )
    return x_user_id


async def get_storage(request: Request) -> StorageBase:
    """Return the application-wide storage backend.

    Args:
        request (`Request`): The incoming FastAPI request.

    Returns:
        `StorageBase`: The storage instance stored in ``app.state``.
    """
    return request.app.state.storage

View on GitHub (pinned to e90f1c7592)

Solutions

  1. Send a non-empty X-User-ID header on every request (e.g. -H 'X-User-ID: user123')
  2. Configure your proxy/gateway to forward the header (proxy_set_header X-User-ID $http_x_user_id in nginx)
  3. In tests, add the header to the client fixture defaults
  4. If you need real auth, wrap the app with middleware that derives X-User-ID from your session/token

Example fix

# before
resp = client.get("/api/skills")

# after
resp = client.get("/api/skills", headers={"X-User-ID": "user123"})
Defensive patterns

Strategy: try-catch

Try / catch

resp = client.get("/api/...")
if resp.status_code == 401 and "X-User-ID" in resp.json().get("detail", ""):
    retry_with_header()

Prevention

When it happens

Trigger: Calling any app endpoint that depends on get_current_user_id (as a FastAPI Depends) without the X-User-ID header, or with an empty value — e.g. curl without -H 'X-User-ID: ...', gateway/proxy stripping the header, or frontend not sending it.

Common situations: Reverse proxy or auth middleware not forwarding custom headers, typos/case issues in header name (though HTTP headers are case-insensitive), integration tests forgetting the header, switching from token auth and assuming identity comes from elsewhere.

Related errors


AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28). Data as JSON: /api/errors/358a4bee3a394fc4. Report an issue: GitHub.