{"record":{"id":"c7bbe52c60504878","repo":"BerriAI/litellm","slug":"internal-server-error-c7bbe5","errorCode":"internal_server_error","errorMessage":"Failed to delete keys got None response from delete_verification_token","messagePattern":"Failed to delete keys got None response from delete_verification_token","errorType":"http","errorClass":"ProxyException","httpStatus":500,"severity":"error","filePath":"litellm/proxy/management_endpoints/key_management_endpoints.py","lineNumber":3423,"sourceCode":"                litellm_changed_by=litellm_changed_by,\n            )\n            num_keys_to_be_deleted = len(data.keys)\n            deleted_keys = data.keys\n        elif data.key_aliases:\n            number_deleted_keys, _keys_being_deleted = await delete_key_aliases(\n                key_aliases=data.key_aliases,\n                prisma_client=prisma_client,\n                user_api_key_cache=user_api_key_cache,\n                user_api_key_dict=user_api_key_dict,\n                litellm_changed_by=litellm_changed_by,\n            )\n            num_keys_to_be_deleted = len(data.key_aliases)\n            deleted_keys = data.key_aliases\n        else:\n            raise ValueError(\"Invalid request type\")\n\n        if number_deleted_keys is None:\n            raise ProxyException(\n                message=\"Failed to delete keys got None response from delete_verification_token\",\n                type=ProxyErrorTypes.internal_server_error,\n                param=\"keys\",\n                code=status.HTTP_500_INTERNAL_SERVER_ERROR,\n            )\n        verbose_proxy_logger.debug(\"/key/delete - deleted_keys=%s\", number_deleted_keys)\n\n        try:\n            assert num_keys_to_be_deleted == len(deleted_keys)\n        except Exception:\n            raise HTTPException(\n                status_code=400,\n                detail={\n                    \"error\": f\"Not all keys passed in were deleted. This probably means you don't have access to delete all the keys passed in. Keys passed in={num_keys_to_be_deleted}, Deleted keys ={number_deleted_keys}\"\n                },\n            )\n\n        verbose_proxy_logger.debug(","sourceCodeStart":3405,"sourceCodeEnd":3441,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/key_management_endpoints.py#L3405-L3441","documentation":"After dispatching the actual deletion, /key/delete asserts the delete helper returned a count; if delete_verification_tokens / alias deletion returned None it raises this ProxyException typed internal_server_error with HTTP 500. A None (as opposed to 0) return is an internal contract violation — typically the delete helper silently swallowed a DB error — not a caller mistake.","triggerScenarios":"POST /key/delete while the database connection drops mid-request; a Prisma error during delete_many being caught and converted to a None result; certain upgrades where the repository delete method's return contract changed.","commonSituations":"Transient DB failover or connection pool exhaustion exactly when the delete ran; Prisma binary/schema mismatch after an upgrade; very rarely a bug — report it with the stack trace if persistent.","solutions":["Retry the request once — if it was a transient DB blip the second attempt usually succeeds (verify keys still exist first).","Check proxy logs for the underlying Prisma/DB exception just before this error; fix that (connectivity, migrations, prisma schema).","If reproducible on current version, open a LiteLLM GitHub issue including the log trace and request shape."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    resp = client.post(\"/key/delete\", json={\"keys\": keys})\n    if resp.status_code == 500 and \"None response\" in resp.text:\n        continue  # one retry for transient DB failure\n    resp.raise_for_status()\n    break\nelse:\n    alert(\"/key/delete returning None from delete_verification_token — check proxy logs\")","preventionTips":["Keep proxy and database logs correlated so the underlying Prisma error for these 500s is findable.","Stabilize DB connectivity (pool sizing, timeouts) to avoid mid-request drops during deletes.","Pin LiteLLM versions in production; this class of contract break usually appears across upgrades."],"tags":["internal-error","database","key-management","litellm-proxy"],"backgroundTag":"database-operation-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}