From ad07d7faadcbba9fc44d26b0db5b97688387e279 Mon Sep 17 00:00:00 2001 From: Imgyu Kim Date: Sat, 21 Mar 2026 18:06:44 +0900 Subject: [PATCH] fix: strip 'openrouter/' prefix from model names (#24234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove early return in get_llm_provider_logic.py that prevented the 'openrouter/' prefix from being stripped. The early return was intended for 'native OpenRouter models' like 'openrouter/free', but no such models exist in the model registry — all OpenRouter models are multi-segment (e.g. 'openrouter/anthropic/claude-3.5-sonnet') and need the prefix stripped before being sent to the OpenRouter API. This regression was introduced in v1.82.3 and caused 400 Bad Request errors for all OpenRouter models. --- .../litellm_core_utils/get_llm_provider_logic.py | 8 -------- tests/local_testing/test_get_llm_provider.py | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/litellm/litellm_core_utils/get_llm_provider_logic.py b/litellm/litellm_core_utils/get_llm_provider_logic.py index 3621841737..2870a92aab 100644 --- a/litellm/litellm_core_utils/get_llm_provider_logic.py +++ b/litellm/litellm_core_utils/get_llm_provider_logic.py @@ -158,14 +158,6 @@ def get_llm_provider( # noqa: PLR0915 ): # handle scenario where model="azure/*" and custom_llm_provider="azure" model = custom_llm_provider + "/" + model - # Native OpenRouter models have IDs like "openrouter/free" where the - # "openrouter/" prefix is part of the actual model name on the API. - # When called from a bridge (e.g. anthropic_messages adapter), - # custom_llm_provider is already resolved, so return early to prevent - # the provider-list stripping below from removing the prefix. - if custom_llm_provider == "openrouter" and model.startswith("openrouter/"): - return model, custom_llm_provider, dynamic_api_key, api_base - if api_key and api_key.startswith("os.environ/"): dynamic_api_key = get_secret_str(api_key) diff --git a/tests/local_testing/test_get_llm_provider.py b/tests/local_testing/test_get_llm_provider.py index 9b07111ea5..019b938842 100644 --- a/tests/local_testing/test_get_llm_provider.py +++ b/tests/local_testing/test_get_llm_provider.py @@ -420,3 +420,19 @@ def test_get_llm_provider_use_proxy_arg_true_with_direct_args(): assert provider == "litellm_proxy" assert key == arg_api_key # Should use the argument key assert base == arg_api_base # Should use the argument base + + +def test_openrouter_model_prefix_stripped(): + """ + GH#24234: OpenRouter models like "openrouter/anthropic/claude-3.5-sonnet" + should have the "openrouter/" prefix stripped before being sent to the API. + The API expects "anthropic/claude-3.5-sonnet", not the full prefixed name. + """ + model, provider, _, _ = litellm.get_llm_provider( + model="openrouter/anthropic/claude-3.5-sonnet" + ) + assert provider == "openrouter" + assert model == "anthropic/claude-3.5-sonnet", ( + f"Expected 'anthropic/claude-3.5-sonnet' but got '{model}'. " + "The 'openrouter/' prefix was not stripped." + )