Skip to content

fix(router): tag-based routing broken when encrypted_content_affinity is enabled - #25347

Merged
krrish-berri-2 merged 1 commit into
mainfrom
litellm_Sameerlite/fix-tag-route-affinity
Apr 9, 2026
Merged

fix(router): tag-based routing broken when encrypted_content_affinity is enabled#25347
krrish-berri-2 merged 1 commit into
mainfrom
litellm_Sameerlite/fix-tag-route-affinity

Conversation

@Sameerlite

Copy link
Copy Markdown
Contributor

Relevant issues

Fixes LIT-2326

Pre-Submission checklist

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Type

🐛 Bug Fix

Changes

EncryptedContentAffinityCheck.async_filter_deployments used request_kwargs.setdefault("litellm_metadata", {}) unconditionally, creating an empty litellm_metadata key for every call type (chat completions, embeddings, etc.). This caused _get_metadata_variable_name_from_kwargs to return "litellm_metadata" instead of "metadata", so tag-based routing looked for tags in the wrong dict and ignored all tag filters.

Fix: only set encrypted_content_affinity_enabled when litellm_metadata already exists in request_kwargs (Responses API path). Chat completions and embeddings never have this key, so no spurious key is created and tag routing works correctly.

Testing

model_list:
  - model_name: gpt-3.5-turbo
    litellm_params:
      model: gpt-3.5-turbo
      api_key: os.environ/OPENAI_API_KEY
      mock_response: "Hello from deployment-1"
      tags: ["mi"]
    model_info:
      id: deployment-1

  - model_name: gpt-3.5-turbo
    litellm_params:
      model: gpt-3.5-turbo
      api_key: os.environ/OPENAI_API_KEY
      mock_response: "Hello from deployment-2"
      tags: ["corp"]
    model_info:
      id: deployment-2

router_settings:
  enable_tag_filtering: true
  optional_pre_call_checks:
    - encrypted_content_affinity
  enable_pre_call_checks: true
image

…s in encrypted_content_affinity_check

Using setdefault('litellm_metadata', {}) unconditionally created an empty
litellm_metadata key for chat completions and embeddings. This caused
_get_metadata_variable_name_from_kwargs to return 'litellm_metadata' instead
of 'metadata', so tag-based routing looked for tags in the wrong dict and
ignored all tag filters.

Fix: only set the encrypted_content_affinity_enabled flag when litellm_metadata
already exists (Responses API path). Chat completions and embeddings never have
this key, so nothing is created and tag routing works correctly.
@vercel

vercel Bot commented Apr 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Apr 8, 2026 2:20pm

Request Review

@codspeed-hq

codspeed-hq Bot commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 16 untouched benchmarks


Comparing litellm_Sameerlite/fix-tag-route-affinity (07d773d) with main (62757ff)

Open in CodSpeed

@greptile-apps

greptile-apps Bot commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a bug where enabling encrypted_content_affinity pre-call check caused tag-based routing to silently break for chat completions and embeddings. The root cause was request_kwargs.setdefault(\"litellm_metadata\", {}) injecting a spurious empty litellm_metadata key into every request, causing _get_metadata_variable_name_from_kwargs to resolve to \"litellm_metadata\" instead of \"metadata\" — so tag filters were looked up in the wrong dict and always missed.

The fix is minimal and precise:

  • encrypted_content_affinity_check.py: Only sets encrypted_content_affinity_enabled when litellm_metadata is already present in request_kwargs (guaranteed for Responses API calls injected by the proxy), leaving chat/embedding request_kwargs untouched.
  • test_encrypted_content_affinity_check.py: Adds two new regression tests verifying the fix — one confirming no spurious key injection for chat completions, one confirming the flag is correctly set when litellm_metadata exists. The bulk of the test file diff is Black auto-formatting (line-length reformats).

Confidence Score: 5/5

Safe to merge — the fix is minimal, correct, and well-tested with targeted regression tests.

The only finding is a P2 style issue (mid-file import in the test file) that has no impact on correctness or runtime behavior. The core fix is sound: replacing unconditional setdefault with a presence-guarded assignment correctly prevents spurious litellm_metadata injection into non-Responses-API paths. The two new regression tests directly reproduce the broken invariant and verify the fix. All remaining diff is Black formatting.

No files require special attention.

Vulnerabilities

No security concerns identified. The change narrows the scope of a side effect (flag injection into request_kwargs) rather than expanding it, and there is no user-controlled data flowing into new paths.

Important Files Changed

Filename Overview
litellm/router_utils/pre_call_checks/encrypted_content_affinity_check.py Core fix: guards encrypted_content_affinity_enabled assignment behind an existence check instead of unconditional setdefault, preventing spurious litellm_metadata injection into non-Responses-API call paths.
tests/test_litellm/router_utils/pre_call_checks/test_encrypted_content_affinity_check.py Two new regression tests for the fix; bulk of remaining changes are Black reformats. Contains a mid-file module-level import for the new tests.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["async_filter_deployments called"] --> B{"'litellm_metadata' in request_kwargs?"}
    B -- "Yes (Responses API path)" --> C["Set encrypted_content_affinity_enabled = True\nin request_kwargs['litellm_metadata']"]
    B -- "No (chat / embeddings path)" --> D["Skip flag injection\n(no spurious key created)"]
    C --> E{"Encoded model_id in input?"}
    D --> E
    E -- "Yes" --> F["Pin request to matching deployment"]
    E -- "No" --> G["Return all healthy deployments\n(normal load balancing)"]
    F --> H["Tag-based routing reads from\ncorrect 'metadata' dict ✓"]
    G --> H
Loading

Reviews (1): Last reviewed commit: "fix(router): don't create litellm_metada..." | Re-trigger Greptile

@krrish-berri-2
krrish-berri-2 self-requested a review April 9, 2026 04:10
@krrish-berri-2
krrish-berri-2 merged commit 3a4ed48 into main Apr 9, 2026
94 of 97 checks passed
@krrish-berri-2
krrish-berri-2 deleted the litellm_Sameerlite/fix-tag-route-affinity branch April 9, 2026 04:11
yuneng-berri added a commit that referenced this pull request Apr 14, 2026
- Add 8 content PRs that merged directly to the release branch outside the listed staging PRs: #23769 (Ramp callback), #25252 (JWT OAuth2 override), #25254 (AWS GovCloud mode), #25258 (batch-limit cleanup), #25334 (router custom_llm_provider), #25345 (Triton embeddings), #25347 (tag-based routing), #25358 (Baseten pricing attribution)
- Add @kedarthakkar to new contributors (first-ever PR via #23769)
- Update RELEASE_NOTES_GENERATION_INSTRUCTIONS: require walking git log range between release tags in addition to staging PRs, and verify new-contributor status per author rather than trusting the GH release body floor
ishaan-berri pushed a commit that referenced this pull request Apr 15, 2026
- Add 8 content PRs that merged directly to the release branch outside the listed staging PRs: #23769 (Ramp callback), #25252 (JWT OAuth2 override), #25254 (AWS GovCloud mode), #25258 (batch-limit cleanup), #25334 (router custom_llm_provider), #25345 (Triton embeddings), #25347 (tag-based routing), #25358 (Baseten pricing attribution)
- Add @kedarthakkar to new contributors (first-ever PR via #23769)
- Update RELEASE_NOTES_GENERATION_INSTRUCTIONS: require walking git log range between release tags in addition to staging PRs, and verify new-contributor status per author rather than trusting the GH release body floor
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…s in encrypted_content_affinity_check (BerriAI#25347)

Using setdefault('litellm_metadata', {}) unconditionally created an empty
litellm_metadata key for chat completions and embeddings. This caused
_get_metadata_variable_name_from_kwargs to return 'litellm_metadata' instead
of 'metadata', so tag-based routing looked for tags in the wrong dict and
ignored all tag filters.

Fix: only set the encrypted_content_affinity_enabled flag when litellm_metadata
already exists (Responses API path). Chat completions and embeddings never have
this key, so nothing is created and tag routing works correctly.
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
- Add 8 content PRs that merged directly to the release branch outside the listed staging PRs: BerriAI#23769 (Ramp callback), BerriAI#25252 (JWT OAuth2 override), BerriAI#25254 (AWS GovCloud mode), BerriAI#25258 (batch-limit cleanup), BerriAI#25334 (router custom_llm_provider), BerriAI#25345 (Triton embeddings), BerriAI#25347 (tag-based routing), BerriAI#25358 (Baseten pricing attribution)
- Add @kedarthakkar to new contributors (first-ever PR via BerriAI#23769)
- Update RELEASE_NOTES_GENERATION_INSTRUCTIONS: require walking git log range between release tags in addition to staging PRs, and verify new-contributor status per author rather than trusting the GH release body floor
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
- Add 8 content PRs that merged directly to the release branch outside the listed staging PRs: BerriAI#23769 (Ramp callback), BerriAI#25252 (JWT OAuth2 override), BerriAI#25254 (AWS GovCloud mode), BerriAI#25258 (batch-limit cleanup), BerriAI#25334 (router custom_llm_provider), BerriAI#25345 (Triton embeddings), BerriAI#25347 (tag-based routing), BerriAI#25358 (Baseten pricing attribution)
- Add @kedarthakkar to new contributors (first-ever PR via BerriAI#23769)
- Update RELEASE_NOTES_GENERATION_INSTRUCTIONS: require walking git log range between release tags in addition to staging PRs, and verify new-contributor status per author rather than trusting the GH release body floor
@reitowo

reitowo commented Jul 17, 2026

Copy link
Copy Markdown

This seems break the encrypted content tagging when stream: true in responses api

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.

3 participants