{"record":{"id":"625fc66e9ad89eee","repo":"BerriAI/litellm","slug":"failed-to-update-key-got-response-none","errorCode":null,"errorMessage":"Failed to update key got response = None","messagePattern":"Failed to update key got response = None","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/management_endpoints/key_management_endpoints.py","lineNumber":2378,"sourceCode":"            _resolve_token_to_update(data=update_key_request, existing_key_row=existing_key_row)\n        ),\n        data=update_key_request,\n        existing_key_row=existing_key_row,\n    )\n\n    # Trigger async hook\n    asyncio.create_task(\n        KeyManagementEventHooks.async_key_updated_hook(\n            data=update_key_request,\n            existing_key_row=existing_key_row,\n            response=response,\n            user_api_key_dict=user_api_key_dict,\n            litellm_changed_by=litellm_changed_by,\n        )\n    )\n\n    if response is None:\n        raise ValueError(\"Failed to update key got response = None\")\n\n    # Extract and format updated key info\n    updated_key_info = response.get(\"data\", {})\n    if hasattr(updated_key_info, \"model_dump\"):\n        updated_key_info = updated_key_info.model_dump()\n    elif hasattr(updated_key_info, \"dict\"):\n        updated_key_info = updated_key_info.dict()\n\n    updated_key_info.pop(\"token\", None)\n\n    return updated_key_info\n\n\nasync def _validate_mcp_servers_for_key_update(\n    data: \"UpdateKeyRequest\",\n    team_obj: Optional[\"LiteLLM_TeamTableCachedObj\"],\n    existing_key_row: LiteLLM_VerificationToken,\n    prisma_client: PrismaClient | None,","sourceCodeStart":2360,"sourceCodeEnd":2396,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/key_management_endpoints.py#L2360-L2396","documentation":"Internal ValueError raised after prisma_client.update_data(token=..., data=...) returns None in _process_single_key_update. update_data returns None when the UPDATE matches no row (the token does not exist in the LiteLLM_VerificationToken table) or the Prisma call failed without raising, so the endpoint treats a null response as a failed key update. It surfaces to the caller as a 500-class error from the management endpoint wrapper.","triggerScenarios":"Updating a key whose token string does not exist in the DB table (typo, already deleted key, unhashed/hashed mismatch), or the Prisma UPDATE throwing internally and returning None — called from /key/update or bulk endpoints via _process_single_key_update with update_key_request.key not matching any row.","commonSituations":"Client passes a key_alias or a partial key instead of the full token; key was deleted concurrently by another admin; DB replica lag or failed migration leaving the row absent; passing the raw key when the row stores the hashed token (or vice versa) so the WHERE token=... matches nothing.","solutions":["Confirm the key exists first: GET /key/info?key=<the exact key you pass in the update> — a miss means wrong/deleted token","Use the exact token value returned by /key/generate (respect any key_decode/hashing settings) in the update body's key field","Check the proxy logs for the preceding Prisma error when the key does exist — fix the DB issue (connectivity, permissions, migration state) it reveals","If the key was deleted, regenerate it instead of updating"],"exampleFix":"# before\nresp = client.post('/key/update', json={'key': 'my-alias', 'max_budget': 5})  # ValueError: Failed to update key got response = None\n\n# after: resolve the real token first\ninfo = client.post('/key/info', json={'key': 'my-alias'})\ntoken = info.json()['keys'][0]['token']\nresp = client.post('/key/update', json={'key': token, 'max_budget': 5})","handlingStrategy":"try-catch","validationCode":"import requests\n\ndef key_exists(base_url, headers, token) -> bool:\n    r = requests.post(f'{base_url}/key/info', headers=headers, json={'key': token}, timeout=10)\n    return r.ok and r.json().get('keys')","typeGuard":null,"tryCatchPattern":"try:\n    update = client.post('/key/update', json={'key': token, **changes})\n    update.raise_for_status()\nexcept ValueError as e:  # sdk-side\n    if 'response = None' in str(e):\n        refresh_token_and_retry()  # token stale/unknown: re-fetch from /key/info\n    raise","preventionTips":["Always resolve the token via /key/info (alias -> token) before updating","Treat cached tokens as perishable: re-fetch when an update misses","Log the exact key used on failure so mismatches are diagnosable"],"tags":["litellm","prisma","key-management","update","null-response","database"],"backgroundTag":"database-update-returned-null","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}