Skip to content

[Bug]: WebChat model picker displays default model after switching sessions, even though model override is persisted #86597

Description

@xuli500177

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

In Control UI WebChat, after selecting a non-default model in one session, switching to another session, and switching back, the model picker shows "Default (configured model)" instead of the previously selected model. However, the model override is correctly persisted on the Gateway — /status confirms the correct override is still active, and messages use the selected model.

Steps to reproduce

  1. Configure a default model (e.g. openai/gpt-4.1).
  2. Open WebChat dashboard with two sessions (A and B) both using the default model.
  3. In session A, use the model picker dropdown to select a different model B (e.g. bedrock/claude-opus-4.5). Verify the picker now shows the selected model.
  4. Switch to session B using the session picker sidebar.
  5. Switch back to session A.
  6. Observe the model picker displays Default (<default model>) instead of the previously selected bedrock/claude-opus-4.5.

Expected behavior

The model picker should display the session's effective model — either the user-selected override (if one exists) or the resolved default. Switching sessions and switching back should not change the displayed model.

Actual behavior

The model picker reverts to showing Default (configured default model) after session switch-and-return. However:

  • /status correctly shows the session is using the previously selected override model.
  • Messages sent in the session correctly use the override model (not the default).
  • The model override dropdown still lists all available models and allows re-selection.

This is a display-only bug: the model is correctly persisted to the Gateway via sessions.patch and used during chat, but the picker component reads a stale or empty value from the client-side chatModelOverrides cache after session switching.

OpenClaw version

2026.5.22 (a374c3a)

Operating system

Ubuntu 24.04 (WSL2 on Windows 11)

Install method

npm global

Model

Any model selected via the WebChat model picker (e.g. deepseek/deepseek-v4-flash, bedrock/claude-opus-4.5); default model differs.

Provider / routing chain

openclaw -> direct configured provider

Additional provider/model setup details

Standard configuration with one or more providers. Default model is set via agents.defaults.model.primary. Issue is model-agnostic and provider-agnostic.

Impact and severity

Affected: All Control UI WebChat users with multiple sessions who switch between sessions after setting a per-session model override.
Severity: Moderate (UI is misleading — shows default but session uses the override; creates false confidence that the override was lost).
Frequency: 100% reproducible (tested with multiple model pairs).
Consequence: Users may think their model selection is lost and manually re-select, or may incorrectly believe per-session model overrides are not working.

Additional information

Root cause analysis (from source code inspection of 2026.5.22):

The WebChat UI maintains a client-side chatModelOverrides map (Dict<sessionKey, modelOverride>) that is populated when the user selects a model via the picker (CW function) or when processing certain Gateway events. The model picker display logic (_U function → bU function → hW component) has this priority:

  1. chatModelOverrides[e.sessionKey] — client-side cache
  2. chatModelOverrides[e.sessionKey] === null — explicitly "use default"
  3. sessionsResult.sessions.find(key).model — fallback to Gateway session data

When the user switches sessions via bV(e, newKey), the flow is:

  • bV → settings saved → US(e)sS(e) (sessions list refresh) + Tx(e) (chat history refresh)
  • After the refresh, the session picker re-renders

The issue is that the chatModelOverrides map is not re-populated from the Gateway session data during the session switch cycle. The Gateway correctly stores the modelOverride (via sessions.patch), and sessions.list returns it in the session model field, but the client-side code path that should read it and populate chatModelOverrides is either missing or not triggered on session switch.

Related issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions