openclaw - ✅(Solved) Fix [Bug]: [Dashboard v2] Model switcher incorrectly concatenates provider prefix when switching between different providers [2 pull requests, 2 comments, 3 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
openclaw/openclaw#52173Fetched 2026-04-08 01:14:46
View on GitHub
Comments
2
Participants
3
Timeline
18
Reactions
0
Author
Timeline (top)
cross-referenced ×10commented ×2labeled ×2closed ×1

When switching models between different providers in Dashboard v2 (chat UI), the model selector incorrectly uses the current provider's prefix instead of the target model's configured provider, resulting in an invalid model ID and "model not allowed" error.

Error Message

When switching models between different providers in Dashboard v2 (chat UI), the model selector incorrectly uses the current provider's prefix instead of the target model's configured provider, resulting in an invalid model ID and "model not allowed" error. 5. Observe the error: GatewayRequestError: model not allowed: modelstudio-cn/kimi-k2.5

Root Cause

When switching models between different providers in Dashboard v2 (chat UI), the model selector incorrectly uses the current provider's prefix instead of the target model's configured provider, resulting in an invalid model ID and "model not allowed" error.

Fix Action

Fixed

PR fix notes

PR #51381: fix(ui): prevent double-qualifying already-qualified model values

Description (problem / solution / changelog)

Summary

Problem: When switching models in the Control UI, resolveServerChatModelValue() blindly prepends the session's default provider to the model string — even when it's already provider-qualified (e.g. ollama/gpt-oss:120b-cloud). This produces invalid refs like anthropic/ollama/gpt-oss:120b-cloud, which the server rejects with model not allowed.

Why it matters: Users with multi-provider setups (Ollama + Anthropic, OpenRouter nested models) cannot switch models in the Control UI without hitting this error.

What changed:

  • Rewrote resolveServerChatModelValue() to use startsWith(provider + "/") guard instead of delegating to buildQualifiedChatModelValue
  • buildQualifiedChatModelValue() is unchanged — it remains a general-purpose builder
  • Added test cases for Together vendor-prefixed IDs, OpenRouter nested IDs, and already-qualified detection
  • Added chat-model-ref.test.ts to vitest include list

What did NOT change:

  • buildQualifiedChatModelValue() is untouched — this PR only changes the call site that resolves server-bound model values
  • normalizeChatModelOverrideValue(), formatChatModelDisplay(), buildChatModelOption() are untouched
  • No changes to server-side model resolution or validation

Change Type

  • Bug fix (non-breaking)

Scope

UI/DX (Control UI model picker)

Linked Issue

Closes #51139 Closes #51306 Closes #51809 Closes #52002 Closes #52061 Closes #52127 Closes #52173 Closes #52474

Security Impact

  • New permissions requested: none
  • Secrets handling changes: none
  • New network calls: none
  • New command/tool execution: none
  • Data access changes: none

Human Verification

I personally verified:

  • pnpm build passes
  • pnpm test -- ui/src/ui/chat-model-ref.test.ts — 8/8 tests pass (5 existing + 3 new)
  • New test: resolveServerChatModelValue("ollama/gpt-oss:120b-cloud", "anthropic") returns "ollama/gpt-oss:120b-cloud" (not "anthropic/ollama/gpt-oss:120b-cloud")
  • New test: resolveServerChatModelValue("openrouter/anthropic/claude-sonnet-4-6", "openrouter") preserves nested path

Evidence

Test Files  1 passed (1)
     Tests  8 passed (8)
  Duration  131ms

git diff --stat upstream/main...HEAD: 3 files changed, 18 insertions(+)

What I Did NOT Verify

  • Not verified: end-to-end in running Control UI with a real multi-provider gateway (tested via unit tests only)
  • Not verified: edge case where a model alias intentionally contains / but is not provider-qualified (no such case exists in the current codebase — createChatModelOverride already treats / as the qualified signal)

Failure Recovery

If this breaks in production:

  • Detection: Model picker shows wrong model or fails to match selected model
  • Rollback: Revert the single guard clause in resolveServerChatModelValue
  • Blast radius: Only affects model selection display/matching — no server-side impact

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 [email protected]

Changed files

  • ui/src/ui/chat-model-ref.test.ts (modified, +33/-0)
  • ui/src/ui/chat-model-ref.ts (modified, +16/-1)
  • vitest.config.ts (modified, +1/-0)

PR #53220: fix(ui): resolve model provider from catalog instead of stale session default

Description (problem / solution / changelog)

lobster-biscuit

Closes #53031 Also fixes #52173, #52482, #51306, #51334, #51139, #51608, #50585, #51809, #51824

Problem

When switching models in the Control UI, the model picker sends the wrong provider prefix. For example, selecting DeepSeek from a session running on ZAI produces zai/deepseek-chat instead of deepseek/deepseek-chat — causing "model not allowed" errors.

This is the root cause behind 9+ independent bug reports across different provider combinations (ZAI/DeepSeek, Ollama/Moonshot, MiniMax/Kimi, etc.).

Root cause

Three call sites use resolveServerChatModelValue(model, modelProvider) which blindly prepends the session's current provider to the bare model name:

  1. ui/src/ui/app-render.helpers.ts:542 — active session model display
  2. ui/src/ui/app-render.helpers.ts:549 — default model display
  3. ui/src/ui/chat/slash-command-executor.ts:158 — /model slash command

The modelProvider from the server reflects the previous model's provider, not the newly selected model's provider.

User impact

Every user who switches between models from different providers in the Control UI gets "model not allowed" errors. Affects all multi-provider setups.

Fix

For bare model names (no /), create a raw ChatModelOverride and resolve the correct provider through normalizeChatModelOverrideValue(), which looks up the model in the catalog and returns the catalog's provider. Falls back to server-provided provider only if catalog lookup fails.

All 3 call sites are fixed. 2 files, +30/-7.

How to verify

  1. Configure 2+ providers (e.g. ZAI + DeepSeek)
  2. Start a session with one provider's model
  3. Switch to another provider's model via UI dropdown
  4. Before: "model not allowed". After: switches correctly.

Tests

chat-model-ref.test.ts covers normalizeChatModelOverrideValue catalog lookup. The fix routes through this existing tested path. No new test needed — the functions are correct, only the call sites were wrong.

🤖 Generated with Claude Code

Changed files

  • ui/src/ui/app-render.helpers.ts (modified, +23/-2)
  • ui/src/ui/chat/slash-command-executor.ts (modified, +7/-5)
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Summary

When switching models between different providers in Dashboard v2 (chat UI), the model selector incorrectly uses the current provider's prefix instead of the target model's configured provider, resulting in an invalid model ID and "model not allowed" error.

Steps to reproduce

  1. Configure two models from different providers in agent/model.json, e.g.:

    • modelstudio-cn/qwen-plus (通义千问)
    • moonshot-cn/kimi-k2.5 (Moonshot)
  2. Open Dashboard v2 chat UI

  3. Start with model A (e.g., 千问)

  4. Use the model picker to switch to model B (e.g., Kimi)

  5. Observe the error: GatewayRequestError: model not allowed: modelstudio-cn/kimi-k2.5

Expected behavior

Switching from modelstudio-cn/qwen-plus to Kimi should request moonshot-cn/kimi-k2.5.

Actual behavior

Dashboard incorrectly requests modelstudio-cn/kimi-k2.5 (wrong provider prefix).

The bug is bidirectional:

  • From 千问 → Kimi: tries modelstudio-cn/kimi-k2.5
  • From Kimi → 千问: tries moonshot-cn/qwen-plus

OpenClaw version

2026.3.13

Operating system

MacOS 26.3.1

Install method

npm global

Model

kimi-k2.5/qwen-plus

Provider / routing chain

gateway → provider

Additional provider/model setup details

"models": { "providers": { "modelstudio-cn": { "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1", "apiKey": "MODELSTUDIO_API_KEY_1", "api": "openai-completions", "models": [ { "id": "qwen-plus", "name": "千问", "api": "openai-completions", "reasoning": false, "input": [ "text" ], "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }, "contextWindow": 200000, "maxTokens": 8192 } ] }, "moonshot-cn": { "baseUrl": "https://api.moonshot.cn/v1", "apiKey": "MOONSHOT_API_KEY_1", "api": "openai-completions", "models": [ { "id": "kimi-k2.5", "name": "Kimi", "api": "openai-completions", "reasoning": false, "input": [ "text" ], "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }, "contextWindow": 200000, "maxTokens": 8192 } ] } } }, "agents": { "defaults": { "model": { "primary": "moonshot-cn/kimi-k2.5" }, "models": { "modelstudio-cn/qwen-plus": { "alias": "千问" }, "moonshot-cn/kimi-k2.5": { "alias": "Kimi" } } } },

Logs, screenshots, and evidence

Impact and severity

This affects users who configure multiple models from different providers (e.g., comparing cloud providers, using regional APIs, or maintaining fallback options). While less common than single-provider setups, it's a valid and documented configuration pattern.

Additional information

No response

extent analysis

Fix Plan

To resolve the issue, we need to update the model selector to use the target model's configured provider instead of the current provider's prefix.

Here are the steps:

  • Update the model.json configuration to include the provider prefix for each model.
  • Modify the model selector code to use the target model's provider prefix when constructing the model ID.

Example code changes:

// Before
const modelId = `${currentProvider}/${targetModel.id}`;

// After
const modelId = `${targetModel.provider}/${targetModel.id}`;

In the agent/model.json file, add a provider field to each model:

"models": {
  "modelstudio-cn/qwen-plus": {
    "alias": "千问",
    "provider": "modelstudio-cn"
  },
  "moonshot-cn/kimi-k2.5": {
    "alias": "Kimi",
    "provider": "moonshot-cn"
  }
}

Verification

To verify the fix, follow these steps:

  1. Update the model.json file with the provider prefix for each model.
  2. Restart the application.
  3. Switch between models from different providers in the Dashboard v2 chat UI.
  4. Verify that the correct model ID is used and the "model not allowed" error is resolved.

Extra Tips

  • Make sure to update the model.json file correctly to include the provider prefix for each model.
  • Test the fix with different model combinations to ensure it works as expected.
  • Consider adding validation to the model selector code to handle cases where the provider prefix is missing or incorrect.

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…

FAQ

Expected behavior

Switching from modelstudio-cn/qwen-plus to Kimi should request moonshot-cn/kimi-k2.5.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: [Dashboard v2] Model switcher incorrectly concatenates provider prefix when switching between different providers [2 pull requests, 2 comments, 3 participants]