litellm - 💡(How to fix) Fix [Bug]: Regression in v1.82.3 - All OpenRouter models broken when custom_llm_provider is set [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#25629Fetched 2026-04-14 05:38:33
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
1
Author
Participants

Error Message

{ "error": { "message": "litellm.BadRequestError: OpenrouterException - {"error":{"message":"openrouter/z-ai/glm-5-turbo is not a valid model ID","code":400}}", "code": "400" } }

Root Cause

Commit 9d7fc307b8 ("fix(openrouter): strip LiteLLM prefix when proxy sets custom_llm_provider") introduced an early return at line 166-167 of get_llm_provider_logic.py that interacts incorrectly with the prefix logic at line 156-159.

Code flow with custom_llm_provider="openrouter", model="z-ai/glm-5-turbo":

# Line 156-159: model doesn't start with "openrouter/", so prefix is added
model.split("/")[0]  # "z-ai" != "openrouter"
model = "openrouter/" + "z-ai/glm-5-turbo"  # → "openrouter/z-ai/glm-5-turbo"

# Line 166-167 (NEW in v1.82.3): early return triggers on the prefix WE JUST ADDED
if custom_llm_provider == "openrouter" and model.startswith("openrouter/"):
    return model, ...  # Returns "openrouter/z-ai/glm-5-turbo" ← BUG

# Line 196-198 (NEVER REACHED): would have correctly stripped the prefix
# model.split("/", 1)[0] == "openrouter" ∈ provider_list
# model = "z-ai/glm-5-turbo"  ← correct

The early return at line 166-167 was intended to preserve native OpenRouter model IDs like openrouter/auto and openrouter/free, but it cannot distinguish between:

  • Models that originally had openrouter/ prefix (native IDs — should preserve)
  • Models that just received the prefix from line 159 (should allow later stripping)

Fix Action

Fix / Workaround

v1.82.0-stable.patch5 (regression confirmed between v1.82.0-stable and v1.82.3-stable)

Code Example

# Line 156-159: model doesn't start with "openrouter/", so prefix is added
model.split("/")[0]  # "z-ai" != "openrouter"
model = "openrouter/" + "z-ai/glm-5-turbo"  # → "openrouter/z-ai/glm-5-turbo"

# Line 166-167 (NEW in v1.82.3): early return triggers on the prefix WE JUST ADDED
if custom_llm_provider == "openrouter" and model.startswith("openrouter/"):
    return model, ...  # Returns "openrouter/z-ai/glm-5-turbo"BUG

# Line 196-198 (NEVER REACHED): would have correctly stripped the prefix
# model.split("/", 1)[0] == "openrouter" ∈ provider_list
# model = "z-ai/glm-5-turbo"  ← correct

---

model_list:
  - model_name: glm-5-turbo
    litellm_params:
      model: z-ai/glm-5-turbo
      custom_llm_provider: openrouter
      api_key: sk-or-xxx

---

{
  "error": {
    "message": "litellm.BadRequestError: OpenrouterException - {\"error\":{\"message\":\"openrouter/z-ai/glm-5-turbo is not a valid model ID\",\"code\":400}}",
    "code": "400"
  }
}

---

_original_model = model  # save before prefixing

if custom_llm_provider and (
    model.split("/")[0] != custom_llm_provider
):
    model = custom_llm_provider + "/" + model

if custom_llm_provider == "openrouter" and _original_model.startswith("openrouter/"):
    return model, custom_llm_provider, dynamic_api_key, api_base

---

OpenrouterException - {"error":{"message":"openrouter/z-ai/glm-5-turbo is not a valid model ID","code":400},"user_id":"org_39FX1KkENb928r9oeqXttVGBkfS"}
Received Model Group=glm-5-turbo
Available Model Group Fallbacks=None
RAW_BUFFERClick to expand / collapse

What happened?

All OpenRouter models fail with is not a valid model ID error when configured with custom_llm_provider="openrouter" (the standard way models are added via the LiteLLM UI/DB). This is a regression introduced in v1.82.3.

Severity: Critical — This breaks ALL OpenRouter model routing for any deployment that uses custom_llm_provider="openrouter", which is the default when adding models through the LiteLLM proxy UI.

Root Cause

Commit 9d7fc307b8 ("fix(openrouter): strip LiteLLM prefix when proxy sets custom_llm_provider") introduced an early return at line 166-167 of get_llm_provider_logic.py that interacts incorrectly with the prefix logic at line 156-159.

Code flow with custom_llm_provider="openrouter", model="z-ai/glm-5-turbo":

# Line 156-159: model doesn't start with "openrouter/", so prefix is added
model.split("/")[0]  # "z-ai" != "openrouter"
model = "openrouter/" + "z-ai/glm-5-turbo"  # → "openrouter/z-ai/glm-5-turbo"

# Line 166-167 (NEW in v1.82.3): early return triggers on the prefix WE JUST ADDED
if custom_llm_provider == "openrouter" and model.startswith("openrouter/"):
    return model, ...  # Returns "openrouter/z-ai/glm-5-turbo" ← BUG

# Line 196-198 (NEVER REACHED): would have correctly stripped the prefix
# model.split("/", 1)[0] == "openrouter" ∈ provider_list
# model = "z-ai/glm-5-turbo"  ← correct

The early return at line 166-167 was intended to preserve native OpenRouter model IDs like openrouter/auto and openrouter/free, but it cannot distinguish between:

  • Models that originally had openrouter/ prefix (native IDs — should preserve)
  • Models that just received the prefix from line 159 (should allow later stripping)

Steps to Reproduce

  1. Configure a model with custom_llm_provider="openrouter" (this is what the UI does):
model_list:
  - model_name: glm-5-turbo
    litellm_params:
      model: z-ai/glm-5-turbo
      custom_llm_provider: openrouter
      api_key: sk-or-xxx
  1. Send any chat completion request targeting this model

  2. Observe error:

{
  "error": {
    "message": "litellm.BadRequestError: OpenrouterException - {\"error\":{\"message\":\"openrouter/z-ai/glm-5-turbo is not a valid model ID\",\"code\":400}}",
    "code": "400"
  }
}

Impact

This affects every OpenRouter model configured with custom_llm_provider="openrouter", except the two native IDs (openrouter/auto, openrouter/free). Any model added through the LiteLLM UI sets custom_llm_provider automatically, so this effectively breaks all UI-configured OpenRouter models.

Both model: "z-ai/glm-5-turbo" and model: "openrouter/z-ai/glm-5-turbo" produce the same error.

Suggested Fix

Track whether the openrouter/ prefix was already present before line 159, so the early return only applies to genuinely native IDs:

_original_model = model  # save before prefixing

if custom_llm_provider and (
    model.split("/")[0] != custom_llm_provider
):
    model = custom_llm_provider + "/" + model

if custom_llm_provider == "openrouter" and _original_model.startswith("openrouter/"):
    return model, custom_llm_provider, dynamic_api_key, api_base

Relevant log output

OpenrouterException - {"error":{"message":"openrouter/z-ai/glm-5-turbo is not a valid model ID","code":400},"user_id":"org_39FX1KkENb928r9oeqXttVGBkfS"}
Received Model Group=glm-5-turbo
Available Model Group Fallbacks=None

Are you a ML Ops Team?

Yes

What LiteLLM version are you on?

v1.82.0-stable.patch5 (regression confirmed between v1.82.0-stable and v1.82.3-stable)

Twitter / LinkedIn details

No response

extent analysis

TL;DR

The most likely fix is to modify the get_llm_provider_logic.py to track whether the openrouter/ prefix was already present before applying the early return condition.

Guidance

  • Identify the lines of code responsible for the regression (166-167 in get_llm_provider_logic.py) and understand how they interact with the prefix logic at lines 156-159.
  • Apply the suggested fix to track the original model before prefixing and use this to determine whether to apply the early return.
  • Verify the fix by testing models with and without the openrouter/ prefix and checking for the is not a valid model ID error.
  • Consider reviewing the commit history to ensure no other changes are affecting the model ID validation.

Example

The suggested fix involves modifying the code as follows:

_original_model = model  # save before prefixing

if custom_llm_provider and (
    model.split("/")[0] != custom_llm_provider
):
    model = custom_llm_provider + "/" + model

if custom_llm_provider == "openrouter" and _original_model.startswith("openrouter/"):
    return model, custom_llm_provider, dynamic_api_key, api_base

This change allows the code to correctly distinguish between native OpenRouter model IDs and those that have had the prefix added.

Notes

This fix assumes that the issue is solely due to the introduced regression in v1.82.3 and that no other changes are affecting the model ID validation. Additional testing and review may be necessary to ensure the fix is comprehensive.

Recommendation

Apply the suggested workaround by modifying the get_llm_provider_logic.py file to track the original model before prefixing and use this to determine whether to apply the early return. This should resolve the is not a valid model ID error for OpenRouter models configured with custom_llm_provider="openrouter".

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING