diff --git a/litellm/router_rust/core.py b/litellm/router_rust/core.py index 900a9d197fd..f7c0d504684 100644 --- a/litellm/router_rust/core.py +++ b/litellm/router_rust/core.py @@ -4421,6 +4421,7 @@ class _Driver: # The primary level reached the end of `async_function_with_fallbacks_common_utils`, the # only place the outcome message is appended: not its early raises, nor its order path. self._explains_failure: bool = False + self._order_chain_ran: bool = False def _blocked(self, response: object, endpoint_name: str) -> str | None: """How the provider blocked a served response, the first check of @@ -4621,6 +4622,7 @@ class _Driver: self._level_errors[at] = last_hop if at == self._base_level: self._explains_failure = False + self._order_chain_ran = True def _logged_off_the_loop(self) -> bool: """Whether litellm logged the attempt's failure on a thread with no running loop. An async @@ -5445,7 +5447,10 @@ class _Driver: ) if ( self._base_level == 0 - and (self._explains_failure or self._is_create_that_may_already_exist(primary)) + and ( + self._explains_failure + or (not self._order_chain_ran and self._is_create_that_may_already_exist(primary)) + ) and self._core._host.dynamic().expose_router_debug_in_errors # pyright: ignore[reportPrivateUsage] # see above and hasattr(primary, "message") ): diff --git a/tests/unit/test_router/test_router_retries.py b/tests/unit/test_router/test_router_retries.py index 324eade8efd..46fd5149fad 100644 --- a/tests/unit/test_router/test_router_retries.py +++ b/tests/unit/test_router/test_router_retries.py @@ -923,10 +923,11 @@ async def test_a_create_that_times_out_on_a_fallback_is_not_sent_to_the_next_fal ) ) - with pytest.raises(openai.APITimeoutError): + with pytest.raises(openai.APITimeoutError) as raised: await _create(_batch_router(api_bases, num_retries=0), create) assert [route.call_count for route in routes] == [1, 1, 0] + assert "No fallback was attempted" not in raised.value.message @pytest.mark.parametrize("unsent_timeout", [httpx.ConnectTimeout, httpx.PoolTimeout])