Repository navigation
Description
Summary
In a new session, after the user manually selects a model via /model and sends the first message, the model picker silently resets back to the agent's default model after the response. The second message — if sent without re-selecting — uses the agent default, not the previously chosen model. Once the user manually selects a model for the second time, the picker sticks and subsequent messages persist correctly.
So the first manual selection is effectively a "one-shot" that silently expires, while any subsequent selection is persistent. The asymmetry is confusing, and the reset is invisible unless the user notices the status bar label has changed.
Repro
- Configure an agent with an explicit
model:{ "$schema": "https://opencode.ai/config.json", "agent": { "build": { "model": "anthropic/claude-opus-4-7" } } } - Open opencode on a fresh session (homepage).
/model→ switch toopenai/gpt-5.4.- Send message 1:
test- Response: GPT-5.4 ✓
- Status bar after response: Claude Opus 4.7 — silently reverted
- Send message 2 (no manual switch):
test- Response: Claude Opus 4.7 ✗ — agent default, not the earlier choice
/model→ switch back toopenai/gpt-5.4.- Send message 3:
test- Response: GPT-5.4 ✓
- Send message 4 (no manual switch):
test- Response: GPT-5.4 ✓ — now persists correctly
Reproduced multiple times; the asymmetric behavior is deterministic. Same pattern reproduces with models routed through custom OpenAI-compatible providers.
Backend fallback is fine; issue is in the frontend state
From packages/opencode/src/session/prompt.ts:932 (createUserMessage):
const model = input.model ?? ag.model ?? (yield* lastModel(input.sessionID))This three-way fallback is reasonable. The observable behavior above implies the UI stops sending input.model on message 2 but resumes sending it from message 3 onward — so the backend correctly falls through to ag.model exactly once. In other words the picker's selectedModel state is being reset exactly once, after the first message of a new session completes.
I didn't pinpoint the frontend line, but the four-step repro makes the behavior deterministic and isolates it to frontend picker state management.
Expected
The picker should persist the user's manual selection across all subsequent messages in the session, including the one immediately after the first response — same as messages 3+ already do.
Impact
- Users unknowingly send their second message to the agent's default model instead of their chosen one
- The reset is not surfaced via toast or warning
- Particularly impactful for users on custom OpenAI-compatible providers where provider-level cost and capability differences matter — silent routing to the wrong backend happens with zero indication
Activity
github-actions commentedon Apr 21, 2026
This issue might be related to existing issues about model selection persistence. Please check:
/modelresets to agent default when switching between Plan and Build modes — similar symptom of session-level model selection not stickingThese are not exact duplicates (the specific trigger here — first message of a new session — appears distinct), but the underlying cause may be shared.
XIYBHK commentedon Apr 21, 2026
Thanks bot — cross-checked all three and I think the likely shared root cause sits in how the frontend tracks per-agent selected model state, and specifically how it decides whether to send
input.modelon each submission.All four issues (this one plus #21351, #6636, #23369) are different triggers of the same underlying asymmetry around
packages/opencode/src/session/prompt.ts:932:The backend fallback order is fine in isolation. What varies across these issues is whether the frontend correctly sends
input.modelon a given submission:input.modelon message 2 of a new session, exactly onceinput.modelon Tab-switch between Plan/Build, so each mode re-resolves to the new agent'sag.modelag.modelon switchNet: these look like four symptoms of one missing invariant — "each agent in a session has its own persistent
selectedModelstate, independent ofag.model, surviving first-message completion, mode switches, subagent dispatch, and session resume". Fixing that one invariant should close this whole cluster.Happy to keep these linked; feel free to triage this as a cluster under a single model-selection-persistence umbrella if that fits the roadmap better.
kagura-chen commentedon Apr 21, 2026
I can take this. The root cause is in
packages/opencode/src/cli/cmd/tui/context/local.tsx— thecreateEffectthat syncs agent model fires on every reactivesync.data.agentrefresh (new object references), not just on actual agent switches. After message 1 completes, sync refreshes → effect fires → overwrites user selection with agent config model. Will submit a fix shortly.coygeek commentedon Apr 25, 2026
OpenCode model-switch bug investigation:
coygeek commentedon Apr 27, 2026
Still not fixed
coygeek commentedon Apr 27, 2026
Reproduction steps below...
coygeek commentedon Apr 27, 2026
Proposed solution:
#23741 (comment)
Fohlen commentedon Apr 30, 2026
I second this as it is PEAK annoying. Please let us know how we can help you with getting this fixed. Thanks!
emcd commentedon May 6, 2026
Would also love to see this prioritized as it has tripped me up a few times when I start a conversation with GPT 5.5 selected to override my default MiniMax M2.7. Then, after the initial turn, the model appears to be automatically reverted to the default (MiniMax M2.7).
(Previously, I have used Codex CLI for GPT interactions and Opencode for interactions with self-hosted models and ones from the Chinese providers, so this was not a big problem for me. But, Codex CLI has become so buggy lately that I am migrating completely to Opencode. Need my overrides in Opencode to stick.)
coygeek commentedon May 6, 2026
This is the only glitch that made me move away from OpenCode.