From c57a5b0f21135b2604306954904feadcfd7e0516 Mon Sep 17 00:00:00 2001 From: Cestercian Date: Sat, 31 Oct 2026 07:16:35 +0000 Subject: [PATCH] fix(caching): keep parent_otel_span out of the cache key The caching handler stamps a fresh span on each request. With provider specific optional params included in the cache key, that span made every lookup miss. Treat it as a LiteLLM-owned kwarg so it stays out of the key. --- litellm/types/litellm_params.py | 1 + tests/unit/caching/test_caching.py | 18 ++++++++++++++++++ tests/unit/types/test_litellm_params.py | 1 + 3 files changed, 20 insertions(+) diff --git a/litellm/types/litellm_params.py b/litellm/types/litellm_params.py index 9f1b35fdce3..dcf3e50a442 100644 --- a/litellm/types/litellm_params.py +++ b/litellm/types/litellm_params.py @@ -345,6 +345,7 @@ class CallState: model_alias_map: Mapping[str, str] | None = None data_residency: str | None = None litellm_logging_obj: "Logging | None" = None + parent_otel_span: object | None = None preset_cache_key: str | None = None cache_key: str | None = None stream_response: "Mapping[str, ModelResponse] | None" = None diff --git a/tests/unit/caching/test_caching.py b/tests/unit/caching/test_caching.py index c4727cbeff0..7a65b23435c 100644 --- a/tests/unit/caching/test_caching.py +++ b/tests/unit/caching/test_caching.py @@ -454,6 +454,24 @@ def test_provider_specific_cache_key_ignores_litellm_owned_kwargs(monkeypatch: p assert cache.get_cache_key(**{**request, "top_k": 6}) != base_key +def test_get_cache_key_ignores_parent_otel_span_when_provider_optional_params_are_cached() -> None: + previous: Final = litellm.enable_caching_on_provider_specific_optional_params + litellm.enable_caching_on_provider_specific_optional_params = True + try: + cache: Final = Cache(type=LiteLLMCacheType.LOCAL) + messages: Final = [{"role": "user", "content": "hi"}] + span_a: Final = object() + span_b: Final = object() + key_with_span_a: Final = cache.get_cache_key(model="gpt-4.1-mini", messages=messages, parent_otel_span=span_a) + key_with_span_b: Final = cache.get_cache_key(model="gpt-4.1-mini", messages=messages, parent_otel_span=span_b) + + assert key_with_span_a == key_with_span_b + assert key_with_span_a == cache.get_cache_key(model="gpt-4.1-mini", messages=messages) + assert key_with_span_a != cache.get_cache_key(model="gpt-4.1-mini", messages=messages, top_k=3) + finally: + litellm.enable_caching_on_provider_specific_optional_params = previous + + def test_cache_key_tells_apart_requests_that_differ_only_in_continuation_token() -> None: cache: Final = Cache(type=LiteLLMCacheType.LOCAL) request: Final = { diff --git a/tests/unit/types/test_litellm_params.py b/tests/unit/types/test_litellm_params.py index 22eb9929e7f..c0afcb0caa8 100644 --- a/tests/unit/types/test_litellm_params.py +++ b/tests/unit/types/test_litellm_params.py @@ -254,6 +254,7 @@ INTERNAL_STATE_NAMES: Final = ( "model_alias_map", "data_residency", "litellm_logging_obj", + "parent_otel_span", "preset_cache_key", "cache_key", "stream_response",