From 155addf3f1f3b2710cd62834daf4f384fbe7c138 Mon Sep 17 00:00:00 2001 From: Prajwal <83531837+prajwal-3-14159@users.noreply.github.com> Date: Sat, 29 Aug 2026 20:14:56 +0900 Subject: [PATCH 1/2] fix(proxy): catch HTTPException cleanly on /key/delete to prevent infinite loop logging --- .../key_management_endpoints.py | 4 +++ .../test_key_management_endpoints.py | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/litellm/proxy/management_endpoints/key_management_endpoints.py b/litellm/proxy/management_endpoints/key_management_endpoints.py index 0d12b012c18..84fb09d46e3 100644 --- a/litellm/proxy/management_endpoints/key_management_endpoints.py +++ b/litellm/proxy/management_endpoints/key_management_endpoints.py @@ -3501,6 +3501,8 @@ async def delete_key_fn( return {"deleted_keys": deleted_keys} except Exception as e: + if isinstance(e, HTTPException): + raise handle_exception_on_proxy(e) verbose_proxy_logger.exception("litellm.proxy.proxy_server.delete_key_fn(): Exception occured - %s", e) raise handle_exception_on_proxy(e) @@ -4251,6 +4253,8 @@ async def delete_verification_tokens( else: raise Exception("DB not connected. prisma_client is None") except Exception as e: + if isinstance(e, HTTPException): + raise verbose_proxy_logger.exception( "litellm.proxy.proxy_server.delete_verification_tokens(): Exception occured - %s", e ) diff --git a/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py index 42e56ceabd3..81e1699fc6a 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py @@ -5150,6 +5150,42 @@ async def test_delete_key_fn_persists_deleted_keys(monkeypatch): assert result["deleted_keys"] == ["sk-token-1"] +@pytest.mark.asyncio +async def test_delete_key_fn_404_not_found(monkeypatch): + """Test that deleting a non-existent key raises a 404 cleanly.""" + from litellm.proxy._types import KeyRequest, ProxyException + from litellm.proxy.management_endpoints.key_management_endpoints import delete_key_fn + from fastapi import HTTPException + + mock_prisma_client = AsyncMock() + mock_user_api_key_cache = MagicMock() + + user_api_key_dict = UserAPIKeyAuth( + user_id="admin-user", + api_key="sk-admin", + user_role=LitellmUserRoles.PROXY_ADMIN.value, + ) + + # Mock find_many to return an empty list, simulating a key that isn't found + mock_prisma_client.verificationtoken.find_many.return_value = [] + + monkeypatch.setattr( + "litellm.proxy.proxy_server.prisma_client", + mock_prisma_client, + ) + + data = KeyRequest(keys=["sk-nonexistent-key"]) + + with pytest.raises(ProxyException) as excinfo: + await delete_key_fn( + data=data, + user_api_key_dict=user_api_key_dict, + litellm_changed_by="admin-user", + ) + + assert "No keys found" in str(excinfo.value) + + @pytest.mark.asyncio async def test_can_delete_verification_token_proxy_admin_team_key(monkeypatch): """Test that team admin can delete team keys from their own team.""" From 4e6877e33d6bdc0cd0ae6be4a73fc9ede0b656c1 Mon Sep 17 00:00:00 2001 From: prajwal-3-14159 <83531837+prajwal-3-14159@users.noreply.github.com> Date: Sat, 29 Aug 2026 23:11:22 +0900 Subject: [PATCH 2/2] chore: re-trigger CI against litellm_internal_staging