From 3453afecf05ee18fee081e669da79a3fc94028aa Mon Sep 17 00:00:00 2001 From: Kylinny Date: Tue, 29 Sep 2026 03:33:20 +0000 Subject: [PATCH] fix(proxy): skip auto-router baseline init when no baseline stamp exists Pre-call hook validated metadata for every anthropic_messages request, but _autorouter_baseline_route is only stamped for auto-routed requests. Non-auto-routed requests raised in model_validate on every call and the broad except turned it into a per-request noise warning, burying genuine initialization failures. Return early when the stamp is absent; malformed stamps still warn. Fixes BerriAI/litellm#43658 --- .../proxy/hooks/autorouter_baseline_cache.py | 2 + .../hooks/test_autorouter_baseline_cache.py | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/litellm/proxy/hooks/autorouter_baseline_cache.py b/litellm/proxy/hooks/autorouter_baseline_cache.py index 0c006730dba..74dc98c12f9 100644 --- a/litellm/proxy/hooks/autorouter_baseline_cache.py +++ b/litellm/proxy/hooks/autorouter_baseline_cache.py @@ -133,6 +133,8 @@ class AutoRouterBaselineCache(CustomLogger): if logging_obj.baseline_cache_context is not None: await invalidate_baseline_cache(logging_obj, "retried_request") return + if "_autorouter_baseline_route" not in metadata: + return request: Final = _Metadata.model_validate(metadata) session: Final = kwargs.get("litellm_session_id") or request.session_id or logging_obj.litellm_session_id if not isinstance(session, str) or not session or len(session) > 256: diff --git a/tests/test_litellm/proxy/hooks/test_autorouter_baseline_cache.py b/tests/test_litellm/proxy/hooks/test_autorouter_baseline_cache.py index c6bb7833310..ccf1c7f415d 100644 --- a/tests/test_litellm/proxy/hooks/test_autorouter_baseline_cache.py +++ b/tests/test_litellm/proxy/hooks/test_autorouter_baseline_cache.py @@ -1,5 +1,6 @@ import asyncio import json +import logging from collections.abc import AsyncIterator, Callable, Generator, Mapping from contextlib import contextmanager from datetime import datetime @@ -324,3 +325,41 @@ async def test_provider_counting_does_not_hold_the_inference_response( assert _observation(await rig.capture.payload()).observation.plan is not None finally: release.set() + + +async def test_missing_baseline_stamp_stays_silent_and_forged_stamp_still_warns( + monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture, +) -> None: + rig: Final = _Rig(monkeypatch) + hook: Final = AutoRouterBaselineCache(None, router=lambda: None) + caplog.set_level(logging.WARNING, logger="LiteLLM Proxy") + + async def invoke(metadata: Mapping[str, object]) -> Logging: + logging_obj: Final = rig.logging() + await hook.async_pre_call_deployment_hook( + { + "litellm_logging_obj": logging_obj, + "litellm_session_id": "baseline-session", + "litellm_metadata": metadata, + }, + CallTypes.anthropic_messages, + ) + return logging_obj + + plain: Final = await invoke({"user_api_key_hash": "test-caller-hash"}) + assert plain.baseline_cache_context is None + assert not [ + record + for record in caplog.records + if record.getMessage() == "Auto-router baseline observation could not be initialized" + ] + + forged: Final = await invoke( + {"user_api_key_hash": "test-caller-hash", "_autorouter_baseline_route": {"forged": True}} + ) + assert forged.baseline_cache_context is None + assert [ + record + for record in caplog.records + if record.getMessage() == "Auto-router baseline observation could not be initialized" + ]