BerriAI/litellm · warning · HTTPException
No keys found for team {data.team_id}
Error message
No keys found for team {data.team_id} What it means
POST /team/key/bulk_update with all_keys_in_team=true queried the team's keys filtered to active ones (blocked=false/null AND (expires is null OR expires > now)) and got zero rows. Because the 'all keys' mode derives its target list from that query, an empty result means there is nothing to update, so the endpoint returns 404 instead of reporting a no-op success. Note the filter excludes blocked and expired keys by design (bulk refresh must not revive admin-disabled keys).
Source
Thrown at litellm/proxy/management_endpoints/key_management_endpoints.py:3222
token="__team_scope_auth_check__",
team_id=data.team_id,
models=[],
)
)
await TeamMemberPermissionChecks.can_team_member_execute_key_management_endpoint(
user_api_key_dict=user_api_key_dict,
route=KeyManagementRoutes.KEY_UPDATE,
prisma_client=prisma_client,
existing_key_row=auth_anchor,
user_api_key_cache=user_api_key_cache,
)
# Block metadata.allowed_passthrough_routes for non-admins — the runtime
# route checker reads it from key/team metadata to grant passthrough.
_check_passthrough_routes_caller_permission(data=data.update_fields, user_api_key_dict=user_api_key_dict)
if not requested_tokens:
raise HTTPException(
status_code=404,
detail={"error": f"No keys found for team {data.team_id}"},
)
existing_by_token: Final = {row.token: row for row in existing_keys}
update_field_dict: Final = data.update_fields.model_dump(exclude_unset=True)
successful_updates: Final[list[SuccessfulKeyUpdate]] = []
failed_updates: Final[list[FailedKeyUpdate]] = []
for token in requested_tokens:
db_token = _hash_token_if_needed(token)
try:
if db_token not in existing_by_token:
raise HTTPException(
status_code=404,
detail={"error": f"Key not found in team {data.team_id}"},
)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Verify the team actually has active keys: GET /team/info (with expand) or POST /v2/key/info filtered by the team.
- If the keys are blocked/expired and you truly want to update them anyway, list their tokens explicitly in key_ids — the explicit path does not filter on blocked/expired.
- Confirm the team_id value matches an existing team (GET /team/info?team_id=...).
Example fix
# before
client.post("/team/key/bulk_update", json={"team_id": tid, "all_keys_in_team": True, "update_fields": fields})
# after
active = [k for k in list_team_keys(tid) if k.get("blocked") is not True and not key_expired(k)]
if not active:
log.warning("team %s has no active keys; nothing to bulk update", tid)
else:
client.post("/team/key/bulk_update", json={"team_id": tid, "key_ids": [k["token"] for k in active][:500], "update_fields": fields}) Defensive patterns
Strategy: try-catch
Validate before calling
active = [k for k in list_team_keys(tid) if not k.get("blocked") and not key_expired(k)]
if not active:
log.warning("team %s has no active keys; skipping bulk update", tid)
return Try / catch
try:
resp = client.post("/team/key/bulk_update", json={"team_id": tid, "all_keys_in_team": True, ...})
resp.raise_for_status()
except HTTPError as e:
if e.response.status_code == 404:
log.warning("no active keys in team %s; nothing to update", tid)
else:
raise Prevention
- Check for active keys immediately before the bulk call instead of trusting a cached count.
- Remember the 'all keys' mode intentionally skips blocked and expired keys — treat both as out of scope.
- Alert when a regularly-updated team suddenly reports zero active keys; it usually signals expiry or a mass block.
When it happens
Trigger: Calling /team/key/bulk_update with all_keys_in_team=true for a team_id whose keys are all expired, all blocked, or that simply has no keys; passing a wrong or stale team_id.
Common situations: Running a scheduled bulk budget refresh after all team keys expired at month end; team keys were bulk-blocked during an incident and the automation still tries to update them; typo'd team_id that exists nowhere (other endpoints also 404).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Key not found in team {data.team_id}
- Maximum {MAX_BATCH_SIZE} keys can be updated at once. Found
- Team {data.team_id} has more than {MAX_BATCH_SIZE} keys. Use
- key_ids must be provided when all_keys_in_team is False
- not_found_error
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/31da22ee0ca9a592.
Report an issue: GitHub.