Skip to content

[Bug]: Control UI model switcher sends wrong provider prefix for cross-provider model switching #50050

@tomcastano

Description

@tomcastano

Bug type

Behavior bug (incorrect output/state without crash)

Summary

The Control UI model picker sends bare model IDs (e.g. k2p5) instead of full provider/model keys (e.g. kimi-coding/k2p5), causing the gateway to prepend the wrong provider and reject the switch with "model not allowed".

Steps to reproduce

  1. Configure multiple providers in openclaw.json (e.g. anthropic, openai-codex, kimi-coding)
  2. Set agent primary model to openai-codex/gpt-5.4
  3. Open the Control UI Chat tab
  4. Use the model dropdown to switch to a model from a different provider (e.g. k2p5 · kimi-coding)
  5. Observe the error banner

Expected behavior

Model switches successfully to kimi-coding/k2p5. The dropdown reflects the new selection and the next message uses the selected model.

Actual behavior

Error banner: "Failed to set model: GatewayRequestError: model not allowed: openai-codex/k2p5"

The UI sends the bare model ID ("k2p5") via sessions.patch. The gateway prepends the current session's provider ("openai-codex") instead of the model's actual provider ("kimi-coding"), producing an invalid key "openai-codex/k2p5" which is not in the allowlist.

Additional issues after page refresh:

  • W_() and G_() also return bare model IDs (ignoring modelProvider), creating duplicate entries in the dropdown
  • getSessionDefaults() falls back to hardcoded DEFAULT_MODEL = "claude-opus-4-6" when agents.defaults.model.primary is not set, showing "Default (claude-opus-4-6)" regardless of the agent's actual primary

OpenClaw version

2026.3.13 (61d171a)

Operating system

Debian 12 (bookworm) / amd64

Install method

npm global

Model

openai-codex/gpt-5.4, anthropic/claude-opus-4-6, kimi-coding/k2p5

Provider / routing chain

openclaw -> openai-codex / anthropic / kimi-coding (direct)

Config file / key location

~/.openclaw/openclaw.json ; agents.defaults.models ; agents.list[].model.primary

Additional provider/model setup details

Three providers configured: anthropic (claude-sonnet-4-6, claude-opus-4-6), openai-codex (gpt-5.4), kimi-coding (k2p5).
Agent "main" has model.primary = "openai-codex/gpt-5.4" with fallbacks to anthropic and kimi.
No agents.defaults.model.primary set (per-agent config only).

Logs, screenshots, and evidence

Gateway log when switching to kimi:
> Failed to set model: GatewayRequestError: model not allowed: openai-codex/k2p5

Gateway log when switching to opus:
> Failed to set model: GatewayRequestError: model not allowed: openai-codex/claude-opus-4-6

Root causes identified in minified dist (verified by patching):

1. K_() in control-ui/assets/index-*.js: <select> option value uses `t.id` instead of `provider/t.id`
2. W_() and G_(): read `session.model` but ignore `session.modelProvider`
3. getSessionDefaults() in reply-*.js: `const DEFAULT_MODEL = "claude-opus-4-6"` used as fallback when no explicit default is configured

BELOW 👇 What it looks like when fixed (with no agents.defaults.primary.model but a primary model defined per agent).

Image

Impact and severity

Affected: All users with multiple providers who use the Control UI model dropdown
Severity: High (completely blocks cross-provider model switching via UI)
Frequency: 100% repro on any multi-provider setup
Consequence: Users cannot switch models across providers in the Control UI. Workaround is using /model command in TUI.

Additional information

Related issues: #48369, #48256, #46480, #46453, #47620

Workaround: Use /model provider/model-id in the TUI or session_status tool.

Local patches applied and verified on dist files:

  • K_(): changed option value from t.id to provider/t.id
  • W_()/G_(): combined modelProvider + '/' + model
  • getSessionDefaults(): added defaultModelExplicit flag, returns null when not explicitly configured
  • Added agentModelProvider/agentModel to sessions.list defaults for per-agent primary resolution

UX suggestion: when no global default is set, hide the "Default" option and label the agent's primary model with "(primary)" in the dropdown.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingbug:behaviorIncorrect behavior without a crash

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions