From 645cf9d3ac72e86efca5571853027b5754eebfd1 Mon Sep 17 00:00:00 2001 From: david-koh Date: Wed, 14 Oct 2026 09:54:56 +0900 Subject: [PATCH 1/2] fix(proxy): hide project creation database errors --- .../management_endpoints/project_endpoints.py | 11 ++++++++++- .../test_project_endpoints_prisma.py | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py b/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py index db419fde1e6..6b6c2ef8e87 100644 --- a/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py +++ b/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py @@ -653,7 +653,16 @@ async def new_project( verbose_proxy_logger.exception( "litellm.proxy.management_endpoints.project_endpoints.new_project(): Exception occured - {}".format(str(e)) ) - raise handle_exception_on_proxy(e) + proxy_exception: Final[ProxyException] = handle_exception_on_proxy(e) + if proxy_exception.code == "500": + raise ProxyException( + message="Internal server error", + type="internal_server_error", + param=None, + code=500, + headers=proxy_exception.headers, + ) from e + raise proxy_exception @router.post( diff --git a/tests/unit/enterprise/proxy/management_endpoints/test_project_endpoints_prisma.py b/tests/unit/enterprise/proxy/management_endpoints/test_project_endpoints_prisma.py index 45697723af1..da2ebb84615 100644 --- a/tests/unit/enterprise/proxy/management_endpoints/test_project_endpoints_prisma.py +++ b/tests/unit/enterprise/proxy/management_endpoints/test_project_endpoints_prisma.py @@ -1238,6 +1238,23 @@ async def test_new_project_flag_on_missing_rpm_tpm_returns_400(monkeypatch): assert "rpm/tpm quota" in str(exc_info.value) +@pytest.mark.asyncio +async def test_new_project_does_not_expose_database_errors(monkeypatch): + internal_detail = "db-internal-marker" + mock_prisma_client = mock.MagicMock() + mock_prisma_client.db.litellm_teamtable.find_unique = mock.AsyncMock(side_effect=RuntimeError(internal_detail)) + monkeypatch.setattr(litellm.proxy.proxy_server, "prisma_client", mock_prisma_client) + monkeypatch.setattr(litellm.proxy.proxy_server, "premium_user", True) + monkeypatch.setattr(litellm.proxy.proxy_server, "general_settings", {}) + + with pytest.raises(ProxyException) as exc_info: + await _run_new_project(NewProjectRequest(team_id="test-team")) + + assert exc_info.value.code == "500" + assert exc_info.value.message + assert internal_detail not in exc_info.value.message + + def _project_update_mocks(monkeypatch, stored_metadata: dict) -> mock.MagicMock: existing_row = mock.MagicMock( team_id=None, budget_id=None, object_permission_id=None, metadata=stored_metadata From 02568c190bed15e0440776357ae796f34a85a2de Mon Sep 17 00:00:00 2001 From: david-koh Date: Wed, 14 Oct 2026 10:04:00 +0900 Subject: [PATCH 2/2] test(proxy): preserve project creation license errors --- .../test_project_endpoints_prisma.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/unit/enterprise/proxy/management_endpoints/test_project_endpoints_prisma.py b/tests/unit/enterprise/proxy/management_endpoints/test_project_endpoints_prisma.py index da2ebb84615..5a15ee9ff41 100644 --- a/tests/unit/enterprise/proxy/management_endpoints/test_project_endpoints_prisma.py +++ b/tests/unit/enterprise/proxy/management_endpoints/test_project_endpoints_prisma.py @@ -1255,6 +1255,17 @@ async def test_new_project_does_not_expose_database_errors(monkeypatch): assert internal_detail not in exc_info.value.message +@pytest.mark.asyncio +async def test_new_project_keeps_license_error(monkeypatch): + monkeypatch.setattr(litellm.proxy.proxy_server, "premium_user", False) + + with pytest.raises(ProxyException) as exc_info: + await _run_new_project(NewProjectRequest(team_id="test-team")) + + assert exc_info.value.code == "403" + assert "enterprise feature" in exc_info.value.message + + def _project_update_mocks(monkeypatch, stored_metadata: dict) -> mock.MagicMock: existing_row = mock.MagicMock( team_id=None, budget_id=None, object_permission_id=None, metadata=stored_metadata