diff --git a/litellm/router.py b/litellm/router.py index fac48b45fb3..fc1b29497f3 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -8697,10 +8697,10 @@ class Router: if isinstance(item, str): _router_model_group = item elif isinstance(item, dict): - if item["hidden"] is True: + if item.get("hidden") is True: return None else: - _router_model_group = item["model"] + _router_model_group = item.get("model", "") else: return None @@ -9299,10 +9299,10 @@ class Router: _router_model_name: str = model_value elif isinstance(model_value, dict): _model_value = RouterModelGroupAliasItem(**model_value) # type: ignore - if _model_value["hidden"] is True: + if _model_value.get("hidden") is True: continue else: - _router_model_name = _model_value["model"] + _router_model_name = _model_value.get("model", "") else: continue diff --git a/tests/router_unit_tests/test_router_helper_utils.py b/tests/router_unit_tests/test_router_helper_utils.py index 65d9d6b925d..5c0550b0571 100644 --- a/tests/router_unit_tests/test_router_helper_utils.py +++ b/tests/router_unit_tests/test_router_helper_utils.py @@ -977,6 +977,56 @@ def test_update_settings(model_list): assert router.allowed_fails == 20 +def test_get_model_group_info_alias_dict_without_hidden_key(model_list): + """Regression test: get_model_group_info must not raise KeyError when a + dict-style model_group_alias entry omits the 'hidden' key. + + RouterModelGroupAliasItem declares 'hidden: bool' as a TypedDict field, but + TypedDict is a type-hint only — Python does NOT inject default values at + runtime. Any user who writes: + + model_group_alias: + "gpt-4-alias": {"model": "gpt-3.5-turbo"} + + gets a plain dict without 'hidden', causing item["hidden"] to raise + KeyError on every request (via set_response_headers -> get_model_group_info). + """ + alias_model_list = list(model_list) + [ + { + "model_name": "gpt-3.5-turbo", + "litellm_params": {"model": "openai/gpt-3.5-turbo", "api_key": "sk-fake"}, + } + ] + router = Router( + model_list=alias_model_list, + model_group_alias={ + "gpt-4-alias": {"model": "gpt-3.5-turbo"}, + }, + ) + + # Must not raise KeyError — 'hidden' key is absent from the alias dict + result = router.get_model_group_info(model_group="gpt-4-alias") + assert result is not None + + # Alias with hidden=True must still return None + router2 = Router( + model_list=alias_model_list, + model_group_alias={ + "secret-alias": {"model": "gpt-3.5-turbo", "hidden": True}, + }, + ) + assert router2.get_model_group_info(model_group="secret-alias") is None + + # Alias with hidden=False (explicit) must return info + router3 = Router( + model_list=alias_model_list, + model_group_alias={ + "visible-alias": {"model": "gpt-3.5-turbo", "hidden": False}, + }, + ) + assert router3.get_model_group_info(model_group="visible-alias") is not None + + def test_common_checks_available_deployment(model_list): """Test if the 'common_checks_available_deployment' function is working correctly""" router = Router(model_list=model_list)