BerriAI/litellm · error · HTTPException

user_id is required. Either pass it as a query parameter or

Error message

user_id is required. Either pass it as a query parameter or authenticate with a user-bound key.

What it means

GET /v2/user/info defaults user_id to the authenticated key's bound user. If no user_id query param was passed AND the key has no user bound to it (user_api_key_dict.user_id is None - typical for a master key or a team-only virtual key), the endpoint returns 400 telling you to pass user_id or authenticate with a user-bound key.

Source

Thrown at litellm/proxy/management_endpoints/internal_user_endpoints.py:1028

    from litellm.proxy.proxy_server import prisma_client

    try:
        if prisma_client is None:
            raise HTTPException(
                status_code=500,
                detail=CommonProxyErrors.db_not_connected_error.value,
            )

        # Handle URL encoding for + characters
        if user_id is not None and " " in user_id:
            user_id = get_user_id_from_request(request=request)

        # Default to self-lookup if no user_id provided
        if user_id is None:
            user_id = user_api_key_dict.user_id

        if user_id is None:
            raise HTTPException(
                status_code=400,
                detail="user_id is required. Either pass it as a query parameter or authenticate with a user-bound key.",
            )

        # Check access — returns the user row if allowed, None otherwise.
        # This avoids a redundant DB fetch since the access check already
        # loads the target user for team-admin verification.
        user_row: Final = await _check_user_info_v2_access(
            user_api_key_dict=user_api_key_dict,
            target_user_id=user_id,
        )

        if user_row is None:
            raise HTTPException(
                status_code=404,
                detail=f"User not found: {user_id}",
            )

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Pass ?user_id=<target> explicitly in the request
  2. Use a user-bound virtual key (created via /key/generate with a user_id) for self-lookup
  3. If you need the caller's own id, fetch it from GET /key/info first and pass it as user_id

Example fix

# before
GET /v2/user/info  -H 'Authorization: Bearer sk-master-key'   # 400 user_id is required

# after
GET /v2/user/info?user_id=user123 -H 'Authorization: Bearer sk-master-key'  # 200
Defensive patterns

Strategy: validation

Validate before calling

import requests

def resolve_user_id(base_url: str, key: str) -> str | None:
    r = requests.get(f"{base_url}/key/info", params={"key": key}, timeout=10)
    r.raise_for_status()
    return r.json()["info"].get("user_id")

# before calling /v2/user/info:
uid = resolve_user_id(BASE, api_key)
params = {"user_id": uid} if uid else {}  # if still None, the call WILL 400

Type guard

function hasResolvedUserId(queryUserId: string | undefined, keyUserId: string | null): boolean {
  return Boolean(queryUserId ?? keyUserId);
}

Try / catch

except requests.HTTPError as e:
    if e.response is not None and e.response.status_code == 400 and "user_id is required" in e.response.text:
        uid = resolve_user_id(BASE, api_key)
        if uid is None:
            raise ValueError("use a user-bound key or pass user_id")
        return retry_with(params={"user_id": uid})
    raise

Prevention

When it happens

Trigger: GET /v2/user/info with no user_id param, authenticated with the master key or a team key generated without a user_id; v1-to-v2 tooling migration using a service key.

Common situations: Testing with the master key; keys created for teams (no attached user); CI scripts that assumed the endpoint returns caller info without parameters.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/3b7d443645b95d98. Report an issue: GitHub.