From 71a1ca68cb3ca379352aaef6f3161070f710a1b6 Mon Sep 17 00:00:00 2001 From: Mubashir Osmani Date: Fri, 17 Jul 2026 23:09:09 +0000 Subject: [PATCH] fix(proxy): validate prompt-cache activity date format Reject start_date/end_date that are not YYYY-MM-DD with a 400 instead of passing malformed strings straight to the daily-spend query, where a string comparison would silently return wrong or empty results. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../analytics_endpoints/analytics_endpoints.py | 9 +++++++++ .../test_analytics_endpoints.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/litellm/proxy/analytics_endpoints/analytics_endpoints.py b/litellm/proxy/analytics_endpoints/analytics_endpoints.py index 8e6f9922470..d40e6bad8cd 100644 --- a/litellm/proxy/analytics_endpoints/analytics_endpoints.py +++ b/litellm/proxy/analytics_endpoints/analytics_endpoints.py @@ -143,6 +143,15 @@ async def get_prompt_cache_activity( detail={"error": "Please provide start_date and end_date"}, ) + for label, value in (("start_date", start_date), ("end_date", end_date)): + try: + datetime.strptime(value, "%Y-%m-%d") + except ValueError: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail={"error": f"{label} must be in YYYY-MM-DD format"}, + ) + from litellm.proxy.proxy_server import prisma_client if prisma_client is None: diff --git a/tests/test_litellm/proxy/analytics_endpoints/test_analytics_endpoints.py b/tests/test_litellm/proxy/analytics_endpoints/test_analytics_endpoints.py index b830563378b..dd282e5bd8d 100644 --- a/tests/test_litellm/proxy/analytics_endpoints/test_analytics_endpoints.py +++ b/tests/test_litellm/proxy/analytics_endpoints/test_analytics_endpoints.py @@ -98,6 +98,20 @@ def test_prompt_cache_activity_requires_dates(client, monkeypatch): assert response.status_code == 400 +def test_prompt_cache_activity_rejects_bad_date_format(client, monkeypatch): + query_raw = AsyncMock(return_value=[]) + _set_prisma(monkeypatch, query_raw) + + response = client.get( + "/global/activity/cache_hits/prompt_caching", + params={"start_date": "07/10/2026", "end_date": "2026-07-18"}, + ) + + assert response.status_code == 400 + assert "start_date must be in YYYY-MM-DD format" in response.text + query_raw.assert_not_awaited() + + def test_prompt_cache_activity_no_prisma(client, monkeypatch): monkeypatch.setattr(proxy_server, "prisma_client", None)