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

  1. Verify the team actually has active keys: GET /team/info (with expand) or POST /v2/key/info filtered by the team.
  2. 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.
  3. 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

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


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