{"record":{"id":"5c2ef9b32fa3795f","repo":"BerriAI/litellm","slug":"key-not-found-in-team-data-team-id","errorCode":null,"errorMessage":"Key not found in team {data.team_id}","messagePattern":"Key not found in team (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"litellm/proxy/management_endpoints/key_management_endpoints.py","lineNumber":3237,"sourceCode":"    _check_passthrough_routes_caller_permission(data=data.update_fields, user_api_key_dict=user_api_key_dict)\n\n    if not requested_tokens:\n        raise HTTPException(\n            status_code=404,\n            detail={\"error\": f\"No keys found for team {data.team_id}\"},\n        )\n\n    existing_by_token: Final = {row.token: row for row in existing_keys}\n    update_field_dict: Final = data.update_fields.model_dump(exclude_unset=True)\n\n    successful_updates: Final[list[SuccessfulKeyUpdate]] = []\n    failed_updates: Final[list[FailedKeyUpdate]] = []\n\n    for token in requested_tokens:\n        db_token = _hash_token_if_needed(token)\n        try:\n            if db_token not in existing_by_token:\n                raise HTTPException(\n                    status_code=404,\n                    detail={\"error\": f\"Key not found in team {data.team_id}\"},\n                )\n\n            # team_id from validated scope, never user payload — drives _check_team_key_limits.\n            update_key_request = UpdateKeyRequest.model_validate(\n                {\n                    \"key\": token,\n                    \"team_id\": data.team_id,\n                    **update_field_dict,\n                }\n            )\n            updated_key_info = await _process_single_key_update(\n                update_key_request=update_key_request,\n                user_api_key_dict=user_api_key_dict,\n                litellm_changed_by=litellm_changed_by,\n                prisma_client=prisma_client,\n                user_api_key_cache=user_api_key_cache,","sourceCodeStart":3219,"sourceCodeEnd":3255,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/key_management_endpoints.py#L3219-L3255","documentation":"During POST /team/key/bulk_update in key_ids mode, LiteLLM first loads the team's existing key rows into a token->row map; a requested key whose (hashed) token is not in that map is recorded as a failed update with this 404 message. The key either belongs to a different team, was deleted, or was mistyped — and because the update runs per key inside a loop, this failure is collected per key rather than aborting the whole batch.","triggerScenarios":"Including a key token that was rotated/deleted between your listing call and the bulk update; passing keys that belong to another team; passing unhashed tokens when the DB stores hashed tokens after enabling KEY_DB checkpoints (note _hash_token_if_needed normalizes this, so the usual cause is wrong team or deleted key).","commonSituations":"Race between an admin deleting keys and your bulk job running; stale key list cached from an earlier export; copying key IDs between environments (dev key sent to prod proxy).","solutions":["Inspect the failed_updates array in the BulkUpdateKeyResponse — only the listed keys failed; the rest were updated.","Re-fetch the current team keys (GET /team/info or /v2/key/info) and rerun the bulk update with the intersection of your list and the live list.","Make your listing and update steps short-lived so keys are less likely to disappear in between; treat per-key 404 as expected and prunable."],"exampleFix":"# before\nresp = client.post(\"/team/key/bulk_update\", json={\"team_id\": tid, \"key_ids\": my_cached_ids, \"update_fields\": fields})\n\n# after\nlive_ids = set(get_team_key_ids(tid))\nusable = [k for k in my_cached_ids if k in live_ids]\nresp = client.post(\"/team/key/bulk_update\", json={\"team_id\": tid, \"key_ids\": usable, \"update_fields\": fields})\nfor f in resp.json().get(\"failed_updates\", []):\n    log.warning(\"key %s failed: %s\", f[\"key\"], f[\"error\"])","handlingStrategy":"try-catch","validationCode":"live_tokens = set(fetch_team_key_ids(tid))\nrequestable = [k for k in my_key_ids if k in live_tokens]\ndropped = set(my_key_ids) - live_tokens\nif dropped:\n    log.warning(\"dropping %d keys no longer in team %s: %s\", len(dropped), tid, dropped)","typeGuard":null,"tryCatchPattern":"# Per-key failures are returned in the response body, not thrown — inspect them:\nresult = client.post(\"/team/key/bulk_update\", json={...}).json()\nfor fail in result.get(\"failed_updates\", []):\n    if \"Key not found in team\" in str(fail.get(\"error\", \"\")):\n        prune_from_local_cache(fail[\"key\"])\n    else:\n        escalate(fail)","preventionTips":["Minimize the window between listing team keys and issuing the bulk update.","Always process failed_updates from BulkUpdateKeyResponse; never assume full success.","Drop keys that 404 from your local state instead of resending them next run."],"tags":["not-found","key-management","bulk-update","per-key-failure","litellm-proxy"],"backgroundTag":"resource-not-found","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}