{"record":{"id":"27ea5fa0e92840d1","repo":"BerriAI/litellm","slug":"invalid-request-type","errorCode":null,"errorMessage":"Invalid request type","messagePattern":"Invalid request type","errorType":"exception","errorClass":"ValueError","httpStatus":500,"severity":"warning","filePath":"litellm/proxy/management_endpoints/key_management_endpoints.py","lineNumber":3420,"sourceCode":"                tokens=data.keys,\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.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                },","sourceCodeStart":3402,"sourceCodeEnd":3438,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/key_management_endpoints.py#L3402-L3438","documentation":"POST /key/delete dispatches on which field of the KeyRequest body is populated: data.keys triggers token deletion, data.key_aliases triggers alias deletion. If both are falsy the handler raises this ValueError ('Invalid request type'), which the endpoint wrapper converts into an error response. In other words: the delete request carried neither keys nor key_aliases.","triggerScenarios":"POST /key/delete with an empty body, {}, {\"keys\": []} and no aliases, or a payload using a wrong field name (e.g. {\"key\": \"sk-...\"} singular, or key_ids).","commonSituations":"Client code building the JSON dynamically and emitting {} when nothing to delete; field-name drift after upgrading from an older/newer API that used a different property; manual curl missing the -d body.","solutions":["Send {\"keys\": [\"sk-...\"]} (list of key tokens) to delete by token, or {\"key_aliases\": [\"alias1\"]} to delete by alias.","Check for typos in the field name — only `keys` and `key_aliases` are recognized.","Skip the API call when your computed delete list is empty."],"exampleFix":"# before\nclient.post(\"/key/delete\", json={\"key\": key_to_delete})\n\n# after\nclient.post(\"/key/delete\", json={\"keys\": [key_to_delete]})","handlingStrategy":"validation","validationCode":"def build_delete_body(keys: list[str] | None = None, key_aliases: list[str] | None = None) -> dict:\n    if keys:\n        return {\"keys\": keys}\n    if key_aliases:\n        return {\"key_aliases\": key_aliases}\n    raise ValueError(\"/key/delete requires non-empty 'keys' or 'key_aliases'\")","typeGuard":"def is_valid_delete_request(keys: list[str] | None, key_aliases: list[str] | None) -> bool:\n    return bool(keys) or bool(key_aliases)","tryCatchPattern":null,"preventionTips":["Route all deletes through one builder that refuses empty payloads.","Remember the accepted fields are exactly `keys` (tokens) and `key_aliases` — never `key` or `key_ids`.","Add a schema check (pydantic/jsonschema) on outgoing admin payloads in integration tests."],"tags":["validation","required-field","key-management","litellm-proxy"],"backgroundTag":"missing-required-field","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}