mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(router): Validate routing_strategy at startup to fail fast with helpful error. (#18624)
Invalid routing_strategy values (e.g., "simple" instead of "simple-shuffle") previously failed silently, causing confusing "No deployments available" errors downstream. This change adds upfront validation in routing_strategy_init() to: - Check if the provided strategy matches valid string values or RoutingStrategy enum - Raise a clear ValueError listing valid options if invalid - Fail fast at startup instead of at request time Fixes behavior reported in #11330 where users had to debug cryptic errors. Valid strategies: simple-shuffle, least-busy, usage-based-routing, latency-based-routing, cost-based-routing, usage-based-routing-v2 Co-authored-by: Flibbert E. Gibbitz <flibbertygibbitz@runelabs.ai>
This commit is contained in:
parent
8c21fcb957
commit
3f4a9d8d08
2 changed files with 84 additions and 0 deletions
|
|
@ -713,6 +713,23 @@ class Router:
|
|||
self, routing_strategy: Union[RoutingStrategy, str], routing_strategy_args: dict
|
||||
):
|
||||
verbose_router_logger.info(f"Routing strategy: {routing_strategy}")
|
||||
|
||||
# Validate routing_strategy value to fail fast with helpful error
|
||||
# See: https://github.com/BerriAI/litellm/issues/11330
|
||||
# Derive valid strategies from RoutingStrategy enum + "simple-shuffle" (default, not in enum)
|
||||
valid_strategy_strings = ["simple-shuffle"] + [s.value for s in RoutingStrategy]
|
||||
|
||||
if routing_strategy is not None:
|
||||
is_valid_string = isinstance(routing_strategy, str) and routing_strategy in valid_strategy_strings
|
||||
is_valid_enum = isinstance(routing_strategy, RoutingStrategy)
|
||||
if not is_valid_string and not is_valid_enum:
|
||||
raise ValueError(
|
||||
f"Invalid routing_strategy: '{routing_strategy}'. "
|
||||
f"Valid options: {valid_strategy_strings}. "
|
||||
f"Check 'router_settings.routing_strategy' in your config.yaml "
|
||||
f"or the 'routing_strategy' parameter if using the Router SDK directly."
|
||||
)
|
||||
|
||||
if (
|
||||
routing_strategy == RoutingStrategy.LEAST_BUSY.value
|
||||
or routing_strategy == RoutingStrategy.LEAST_BUSY
|
||||
|
|
|
|||
|
|
@ -79,6 +79,73 @@ def test_routing_strategy_init(model_list):
|
|||
)
|
||||
|
||||
|
||||
def test_routing_strategy_init_invalid_strategy(model_list):
|
||||
"""Test that invalid routing_strategy raises ValueError with helpful message.
|
||||
|
||||
See: https://github.com/BerriAI/litellm/issues/11330
|
||||
Invalid strategies like 'simple' (without '-shuffle') should fail fast
|
||||
with a clear error, not silently cause 'No deployments available' errors.
|
||||
"""
|
||||
router = Router(model_list=model_list)
|
||||
|
||||
# Test common mistake: "simple" instead of "simple-shuffle"
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
router.routing_strategy_init(
|
||||
routing_strategy="simple",
|
||||
routing_strategy_args={}
|
||||
)
|
||||
|
||||
# Verify error message is helpful
|
||||
error_msg = str(exc_info.value)
|
||||
assert "Invalid routing_strategy" in error_msg
|
||||
assert "simple" in error_msg
|
||||
assert "simple-shuffle" in error_msg # Suggests the correct option
|
||||
# Verify error message tells user WHERE to fix it
|
||||
assert "config.yaml" in error_msg
|
||||
assert "router_settings.routing_strategy" in error_msg
|
||||
assert "Router SDK" in error_msg
|
||||
|
||||
# Test completely invalid strategy
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
router.routing_strategy_init(
|
||||
routing_strategy="not-a-real-strategy",
|
||||
routing_strategy_args={}
|
||||
)
|
||||
assert "Invalid routing_strategy" in str(exc_info.value)
|
||||
|
||||
|
||||
def test_routing_strategy_init_valid_string_strategies(model_list):
|
||||
"""Test that all valid string routing strategies work without error.
|
||||
|
||||
Valid strategies are derived from RoutingStrategy enum values plus 'simple-shuffle'.
|
||||
"""
|
||||
from litellm.types.router import RoutingStrategy
|
||||
|
||||
router = Router(model_list=model_list)
|
||||
|
||||
# All strategies from enum + simple-shuffle (default, not in enum)
|
||||
valid_strategies = ["simple-shuffle"] + [s.value for s in RoutingStrategy]
|
||||
|
||||
for strategy in valid_strategies:
|
||||
# Should not raise
|
||||
router.routing_strategy_init(
|
||||
routing_strategy=strategy, routing_strategy_args={}
|
||||
)
|
||||
|
||||
|
||||
def test_routing_strategy_init_valid_enum_strategies(model_list):
|
||||
"""Test that RoutingStrategy enum values work without error."""
|
||||
from litellm.types.router import RoutingStrategy
|
||||
|
||||
router = Router(model_list=model_list)
|
||||
|
||||
for strategy in RoutingStrategy:
|
||||
# Should not raise when passing enum directly
|
||||
router.routing_strategy_init(
|
||||
routing_strategy=strategy, routing_strategy_args={}
|
||||
)
|
||||
|
||||
|
||||
def test_print_deployment(model_list):
|
||||
"""Test if the api key is masked correctly"""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue