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
- Pass ?user_id=<target> explicitly in the request
- Use a user-bound virtual key (created via /key/generate with a user_id) for self-lookup
- 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
- Always pass an explicit user_id to /v2/user/info in service-key scripts
- Create user-bound virtual keys for flows that need self-lookup
- Resolve the caller's identity once via /key/info and thread it through requests
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Either user_id or user_email must be provided
- max_budget cannot be negative. Received: {data.max_budget}
- soft_budget cannot be negative. Received: {data.soft_budget}
- soft_budget ({data.soft_budget}) must be strictly lower than
- Model '{m}' not in team's allowed models. Team allowed model
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/3b7d443645b95d98.
Report an issue: GitHub.