Skip to content

fix(caching): forward metadata to valkey semantic cache sync embedding calls - #35441

Open
nickleodoen wants to merge 1 commit into
BerriAI:litellm_internal_stagingfrom
nickleodoen:fix/valkey-semantic-sync-embedding-metadata
Open

fix(caching): forward metadata to valkey semantic cache sync embedding calls#35441
nickleodoen wants to merge 1 commit into
BerriAI:litellm_internal_stagingfrom
nickleodoen:fix/valkey-semantic-sync-embedding-metadata

Conversation

@nickleodoen

@nickleodoen nickleodoen commented Aug 1, 2026

Copy link
Copy Markdown

Problem this solves:

How it solves it:

  • Forward metadata=kwargs.get("metadata") in sync set_cache/get_cache
  • Brings Valkey in line with the redis and qdrant backends
  • Adds two sync regression tests mirroring the existing async pair

Relevant issues

Follow-up to #32295, which fixed _get_async_embedding at lines 282/301 but left the
two sync _get_embedding callers at lines 243/262 untouched.

Type

🐛 Bug Fix

Changes

ValkeySemanticCache.set_cache and get_cache called self._get_embedding(prompt)
with no metadata. The inherited RedisSemanticCache._get_embedding feeds that
argument to build_router_embedding_metadata() before router.embedding(...), and its
own docstring says it does so "mirroring _get_async_embedding".

Across the three semantic-cache backends there are six sync embedding call sites.
Valkey's two were the only ones dropping metadata:

backend sync call sites forwards metadata
qdrant_semantic_cache.py 246, 285 yes
redis_semantic_cache.py 393, 430 yes
valkey_semantic_cache.py 243, 262 no

Impact: on a sync completion() against cache_type: valkey-semantic with a
Router-served embedding deployment, the embedding call loses user_api_key,
user_api_key_team_id, Bedrock aws_role_name, etc. Per-deployment auth can then fail,
and since set_cache/get_cache swallow exceptions the failure surfaces only as a
permanently cold cache. The async path was already correct, so this is sync-only.

Scope is limited to the two argument lists plus tests.

Pre-Submission checklist

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

A production e2e needs ElastiCache for Valkey 8.2+ running valkey-search, which I don't
have access to. Instead, below is a fully unmocked reproduction exercising the real
code path: a real litellm.Router, a real ValkeySemanticCache, real proxy globals, and
a real litellm CustomLogger observing what the Router actually received. Nothing is
patched or stubbed. Embeddings are served by a local HTTP server implementing the OpenAI
embeddings API, so the run costs $0. Happy to attach the script if useful.

litellm valkey semantic cache -- sync embedding metadata
base: origin/litellm_internal_staging @ 23de7a15d

Unmocked reproduction. Real litellm.Router, real ValkeySemanticCache, real proxy
globals, real litellm CustomLogger observing what the Router actually received.
Nothing patched or stubbed. Embeddings served by a local HTTP server implementing
the OpenAI embeddings API, so the run costs $0.

######## BEFORE (unfixed source) ########
====================================================================
  metadata the Router actually received, per embedding call
====================================================================

  call #1  (sync set_cache)
    semantic-cache-embedding : True
    user_api_key             : None
    user_api_key_team_id     : None
    user_api_key_alias       : None
    ==> METADATA DROPPED

  call #2  (sync get_cache)
    semantic-cache-embedding : True
    user_api_key             : None
    user_api_key_team_id     : None
    user_api_key_alias       : None
    ==> METADATA DROPPED

====================================================================

######## AFTER (fix applied) ########
====================================================================
  metadata the Router actually received, per embedding call
====================================================================

  call #1  (sync set_cache)
    semantic-cache-embedding : True
    user_api_key             : sk-proof-1234
    user_api_key_team_id     : team-abc
    user_api_key_alias       : nikhil-key
    ==> CARRIES request metadata

  call #2  (sync get_cache)
    semantic-cache-embedding : True
    user_api_key             : sk-proof-1234
    user_api_key_team_id     : team-abc
    user_api_key_alias       : nikhil-key
    ==> CARRIES request metadata

====================================================================

Unit tests (tests/test_litellm/caching, base 23de7a1):

  • unfixed source + the two new tests: 2 failedassert None == {'user_api_key': 'sk-test'}
  • with the fix: 263 passed (261 pre-existing + 2 new)

Final Attestation

  • The tests check the right things, including the edge cases

ValkeySemanticCache.set_cache/get_cache called _get_embedding(prompt)
without metadata, so the sync path dropped the request metadata that
_get_embedding forwards to build_router_embedding_metadata(). Router-served
embedding deployments therefore lost per-deployment auth context (user_api_key,
team id, Bedrock aws_role_name) on sync completion() calls, and because both
methods swallow exceptions the resulting failures were a silent cache bypass.

The async twins were fixed in BerriAI#32295 but the sync callers were missed. Both
sibling backends already pass metadata on their sync paths
(RedisSemanticCache 393/430, QdrantSemanticCache 246/285), so Valkey was the
only backend diverging.

Adds sync regression tests mirroring the existing async ones. Both fail on the
unfixed code with metadata == None.
@CLAassistant

CLAassistant commented Aug 1, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@greptile-apps

greptile-apps Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR aligns synchronous Valkey semantic-cache embedding calls with the existing Redis, Qdrant, and asynchronous Valkey paths

  • Forwards request metadata from synchronous cache reads and writes to the inherited embedding helper
  • Adds focused regression coverage for both synchronous call sites

Confidence Score: 5/5

The PR appears safe to merge; the implementation matches established sibling paths and the regression tests cover both corrected call sites

The inherited helper accepts optional metadata, copies it before adding semantic-cache context, and the new calls now behave consistently with Redis, Qdrant, and asynchronous Valkey implementations

Important Files Changed

Filename Overview
litellm/caching/valkey_semantic_cache.py The two synchronous embedding calls now forward metadata using the established semantic-cache backend pattern, with no identified regression
tests/test_litellm/caching/test_valkey_semantic_cache.py Adds focused tests confirming metadata reaches both synchronous embedding call sites while preserving cache read and write behavior

Reviews (1): Last reviewed commit: "fix(caching): forward metadata to valkey..." | Re-trigger Greptile

@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing nickleodoen:fix/valkey-semantic-sync-embedding-metadata (8d19b10) with litellm_internal_staging (23de7a1)

Open in CodSpeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants