BerriAI/litellm · warning · HTTPException
Team {data.team_id} has more than {MAX_BATCH_SIZE} keys. Use
Error message
Team {data.team_id} has more than {MAX_BATCH_SIZE} keys. Use `key_ids` to update in batches of {MAX_BATCH_SIZE}. What it means
On POST /team/key/bulk_update with all_keys_in_team=true, LiteLLM fetches the team's active keys (not blocked, not expired) with take=MAX_BATCH_SIZE+1. If it gets back more than 500 rows it aborts with this 400 rather than silently updating only the first 500. It is a completeness guard: the 'all keys' mode is only allowed when it can actually mean all keys.
Source
Thrown at litellm/proxy/management_endpoints/key_management_endpoints.py:3170
if data.all_keys_in_team:
# "all" excludes blocked/expired — bulk refresh shouldn't revive a key an admin disabled.
# `blocked` is Boolean? with no default; `/key/generate` writes NULL. Prisma's `NOT`
# excludes NULLs, so explicitly OR `false` with `null` to include them.
now: Final = datetime.now(timezone.utc)
existing_keys = await VerificationTokenRepository(prisma_client).table.find_many(
where={
"team_id": data.team_id,
"AND": [
{"OR": [{"blocked": False}, {"blocked": None}]},
{"OR": [{"expires": None}, {"expires": {"gt": now}}]},
],
},
order={"token": "asc"},
take=MAX_BATCH_SIZE + 1,
)
if len(existing_keys) > MAX_BATCH_SIZE:
raise HTTPException(
status_code=400,
detail={
"error": f"Team {data.team_id} has more than {MAX_BATCH_SIZE} keys. Use `key_ids` to update in batches of {MAX_BATCH_SIZE}."
},
)
requested_tokens = [row.token for row in existing_keys]
else:
if data.key_ids is None or len(data.key_ids) == 0:
raise HTTPException(
status_code=400,
detail={"error": "key_ids must be provided when all_keys_in_team is False"},
)
# Dedupe by hashed form — duplicates collapse to one update.
requested_tokens = []
hashed_key_ids: Final = []
seen_hashes: Final = set()
for k in data.key_ids:
h = _hash_token_if_needed(k)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Switch to the key_ids mode: query the team's key tokens (e.g. GET /team/info with expand keys, or /key/info batch) and then POST them in chunks of <=500 with all_keys_in_team omitted/false.
- If most keys are stale, clean up blocked/expired keys first — they are excluded from the 500 count, so pruning may drop the team under the limit.
- Split very large teams into multiple smaller teams if bulk operations are a regular workflow.
Example fix
# before
client.post("/team/key/bulk_update", json={"team_id": tid, "all_keys_in_team": True, "update_fields": {...}})
# after
keys = get_all_team_key_ids(tid) # via /team/info or /v2/key/info
for i in range(0, len(keys), 500):
client.post("/team/key/bulk_update", json={
"team_id": tid,
"key_ids": keys[i:i+500],
"update_fields": {...},
}) Defensive patterns
Strategy: validation
Validate before calling
# Before using all_keys_in_team, check the team's active key count
info = client.get("/team/info", params={"team_id": tid}).json()
active_keys = count_active_team_keys(info) # exclude blocked/expired
if active_keys > 500:
key_ids = fetch_team_key_ids(tid) # then chunk these Type guard
def can_use_all_keys_mode(active_key_count: int) -> bool:
return active_key_count <= 500 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 == 400 and "more than" in e.response.text:
switch_to_chunked_key_ids_mode(tid) Prevention
- Monitor team key counts and alert before a team crosses 500 active keys.
- Prefer explicit key_ids lists in automation — 'all keys' mode is inherently fragile at scale.
- Prune blocked/expired keys regularly; they no longer count toward the 500 limit.
When it happens
Trigger: POST /team/key/bulk_update with {"team_id": ..., "all_keys_in_team": true} on a team that has 501 or more active (unblocked, unexpired) keys.
Common situations: Bulk-rotating budgets or metadata on a large organization-wide team; teams grown past 500 keys through automated key issuance; a 'rotate all team keys' admin script.
Related errors
- Maximum {MAX_BATCH_SIZE} keys can be updated at once. Found
- key_ids must be provided when all_keys_in_team is False
- No keys found for team {data.team_id}
- Key not found in team {data.team_id}
- max_budget ({_requested_max_budget}) cannot be set without s
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/28997a3f2ba3a75a.
Report an issue: GitHub.