fix(router): leave out the no-fallback note when a create stops after an order fallback

A create that fails at a later order level after an earlier level fell back now ends without
the "No fallback was attempted" note, since a fallback did run. The proxy's notice that the
provider may already hold the file or batch still comes through
This commit is contained in:
mateo-berri 2026-11-05 15:07:32 -08:00
parent 811ec5ffd9
commit baf77a7f06
2 changed files with 8 additions and 2 deletions

View file

@ -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")
):

View file

@ -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])