Repository navigation
fix(caching): key response cache by router model group in litellm_metadata - #44542
Conversation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
bugbot run |
|
…e placement Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
bugbot run |
…metadata /v1/responses routes through the router with model_group in litellm_metadata, which the cache key ignored, so identical requests to different model groups sharing one underlying model hit each other's cached responses Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
bugbot run |
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 5d5a47f. Configure here.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
TLDR
Problem this solves:
mainis red inunit,integration-management(-replica),integration-accounting,integration-extensions, plus parts ofintegration-providersandintegration-costHow it solves it:
Cache._get_model_param_value: it now readsmodel_groupfromlitellm_metadatatoo, so/v1/responsescache entries stop leaking across model groupsFailures fixed
Red scheduled run on
main(pipeline 90845, sha1d52985d03), same failures in 90840, 90836 and 90824maintests/unit/proxy/proxy_server/test_routes_model_cost_map.py::test_reload_model_cost_map_surfaces_the_blob_id_of_the_bytes_served_on_every_status_surfacemodels_countwas compared tolen(litellm.model_cost), which includes models other tests registered in the same xdist worker (4472 == 4477)tests/integration/management/test_vector_store_file_list_managed_ids.py::test_provider_errors_reach_the_caller_and_other_models_keep_mapping[401,404,500]codeand the mappedtypeper statustests/integration/authorization/test_team_scoped_models.py::test_v2_model_info_reports_a_team_model_to_team_and_non_team_keysmodel_name=, which/v2/model/infodoes not accept, so the filter was ignored and the new deployments showed upmodelfiltertests/integration/spend/test_roi_branch_spend.py::test_documented_header_and_body_tags_reach_recorded_branch_and_pr_cost0.011 == 0.033)tests/integration/pricing/test_per_second_pricing.py::test_streaming_chat_per_second_pricing_covers_the_full_stream[new_field]GET /v1/modelslanded in the observations next to the single chat calltests/integration/observability/test_otel_v1_request_trace.pyand 8 tests intests/integration/observability/test_otel_excluded_services.pybatch_write_to_dbcost-callback span was removed on purpose; the spend flush is now its ownpostgres.update LiteLLM_VerificationTokentracetests/integration/routing/test_stale_cost_map_boot.py::test_config_deployment_dropped_by_stale_boot_cost_map_is_restored_after_reloadmethodandapi_keytest_case_bills_expected_cost[perplexity/pplx-decider-v1-27b-decisions],[claude-sonnet-5-messages_upstream_500_zero_spend]/v1/messageswithoutmax_tokensis now a 400 before the upstreammax_tokensso the case still reaches the upstream 500test_case_bills_expected_cost[gpt-5.6-responses_web_search_medium],[gpt-5.6-responses_web_search_reported_count_mixed_actions],[gpt-5.6-responses_web_search_reported_count_open_page_only]web_search_medium, exposing a latent cache bugmodel_groupinlitellm_metadatafor/v1/responses, and the cache key only readmetadata, so it fell back to the sharedopenai/gpt-5.6and one case was served another's cached response (0.021488 != 0.008988, or spend0.0)_get_model_param_valuereadsmodel_groupandcaching_groupsfrommetadataandlitellm_metadatain bothkwargsandlitellm_paramsDeferred
Still red on
mainand not claimed here, left for the next run:integration-providers:test_bedrock_mantle_claude_chat_wire.py::test_health_check_on_a_mantle_claude_deployment_probes_the_native_messages_route,test_bedrock_stream_timeout_wire.py::test_c8_the_bedrock_passthrough_stream_already_retries_at_the_deployment_timeoutintegration-cost:claude-sonnet-5-stream_no_usageandclaude-sonnet-5-stream_no_usage_image_input(recounted prompt tokens 48 vs 47 and 303 vs 301, red since the 2026-10-03 12:09 run, range a76ba8c..e768ad5, most likely 7b432d7 (fix(proxy): stamp the client alias on a copy of each streamed chunk so pricing sees the deployment model #44341))integration-providers/build_and_test: xAI provider jobs fail with provider errors onmaintoo, not codeintegration-database-replica:test_managed_file_flat_ids_index.py,test_partition_transactions.pyintegration-mcp,integration-database: no stable test-level failure signature yetintegration-security: the S2 route sweep intermittently getsRemoteProtocolErroronGET /organization/daily/activity*asinternal_user, the same signature that failedmainin pipelines 90758 and 90795, so it is a flake owned by the deflake automation. It failed here in 2240853, and in the rerun, then passed all 131 tests in rerun 2241029 at the tip. The failing tests also passed 2 of 2 locally at both base and headtest_azure_storage_chaos,test_passthrough_upstream_error_chaos,test_get_favicon_*, plus one-offunitfailures on this branch intest_arize_dynamic_paramsandtest_premium_check_receives_the_field_name, and anintegration-extensionsproxy that exited before readiness intest_guardrail_effects.pyproxy-behaviorandroi-databasefailed only in their Codecov upload step at30a8b32b19, a signature check that was red onmainat the same timeCircleCI on this branch
ce7ed5b1f5864d9844fd, rerun from failed build_and_test and integration. Every claimed test passes there30a8b32b19, after the cache key fix. The threegpt-5.6-responses_web_search_*cases pass in integration-cost and again in its rerun5d5a47fbfe, after merging currentmain. The threegpt-5.6-responses_web_search_*cases pass in integration-cost,unitand every claimed job are green, and the remaining reds matchmainpipeline 90859 at02f61c9c42Pre-Submission checklist
Screenshots / Proof of Fix
The test changes are proven by the previously red CircleCI jobs passing on this branch, linked above
For the cache fix, two model groups
group-aandgroup-bboth pointing atopenai/gpt-5.4-nanowithcache: true(local), real OpenAI calls, the same/v1/responsesbody sent togroup-athengroup-b, baseorigin/mainon :4001 and this branch on :4002On base,
group-bwas answered fromgroup-a's cache entry. On this branch it reaches its own deployment, and repeating the same request togroup-ais still a cache hit on both sides (x-litellm-cache-key: 92b0c7f37e98...on :4002)Type
Bug Fix
Test
Caveats (if any)
Low
Final Attestation
Link to Devin session: https://app.devin.ai/sessions/eee2353031f946a0a9f5f4787568e664
Open in Devin Desktop: https://app.devin.ai/desktop/session/eee2353031f946a0a9f5f4787568e664?variant=devin
Requested by: @mateo-berri
Note
Medium Risk
The cache key change affects response caching for router model groups (especially
/v1/responses); incorrect metadata precedence could still mis-key caches, but the fix narrows cross-group leakage.Overview
Aligns red CircleCI integration and unit tests with intentional behavior on
main, and fixes a cache key bug where/v1/responsescould share entries across router model groups.Cache fix:
Cache._get_model_param_valuenow resolvesmodel_groupandcaching_groupsfrommetadataandlitellm_metadataon both top-level kwargs andlitellm_params, so cache keys respect the router’s model group instead of collapsing to the underlying provider model.Test updates (same strictness, new expectations):
postgres.update LiteLLM_VerificationTokenon its own trace, notbatch_write_to_dbon the request trace; tenant postgres exclusion assertions follow suit.type;/v2/model/infofilters withmodel=notmodel_name=.method/api_key; ROI tag test uses distinct prompts and expects three upstream calls; messages cost case sendsmax_tokens; per-second pricing ignores non-POST observations.models_countmatches the served finalized map, not polluted globallitellm.model_cost.Reviewed by Cursor Bugbot for commit 5d5a47f. Bugbot is set up for automated code reviews on this repo. Configure here.