You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
TUI footer shows stale default provider/model after switching via /models #23741
After switching models/providers from the TUI using /models, OpenCode sends the prompt to the newly selected provider correctly, but the footer/input status bar still shows the original default provider/model instead of the active one.
This appears to be a UI state bug: the actual request uses the selected provider, but the bottom bar is not updated.
Steps to reproduce
Start OpenCode normally from the terminal:
opencode
Make sure the default model/provider is something else first (for example GPT-5.4 via GitHub Copilot).
Open the model picker with /models.
Switch to another provider/model, for example:
Kimi K2.6
GLM 5.1 / Z-AI Coding Plan
Send a message.
Actual behavior
The response is generated by the newly selected provider/model.
The conversation output also reflects the new provider/model.
But the footer/input status bar at the bottom still shows the old default provider/model (for example GPT-5.4 GitHub Copilot) instead of the currently active one.
Expected behavior
The footer/input status bar should always reflect the active session model/provider after a /models switch.
Notes
I reproduced this with multiple providers, not just Kimi.
Example pattern:
Default provider shown before switch: GPT-5.4 GitHub Copilot
Switched provider actually used: Kimi K2.6
Footer still incorrectly shows: GPT-5.4 GitHub Copilot
This started happening within roughly the last week.
Launch opencode with an alias 'minimax' opencode -m minimax-coding-plan/MiniMax-M2.7
This is what appears on screen:
3. Send a message, and this is what appears on screen:
4. Notice that the model is routing to the wrong provider (since my limit of Github Copilot has ran out). Its clearly using/routing the wrong model. It should be Minimax, but its trying to use GPT-5.4 (since its my default model in OpenCode):
To get this session back to normal, i now have to do the following workaround:
Press ESC on the keyboard.
type /model, switch to minimax
copy the previous message, paste it again, now it proceeds (see below)
Issue #23741: Model Reverts to Default After First Message When Launched with -m
Summary
When launching OpenCode with a specific model via opencode -m <model>, the model shown in the status bar appears correct initially, but after the first message completes (or even before the first message, depending on bootstrap timing), it silently reverts to the user's default/agent-configured model.
Root cause: A createEffect in local.tsx synchronizes the agent's configured model into the per-agent model store, which overwrites the CLI -m override. The CLI model lives at Priority 3 (fallback), but the effect promotes the agent model to Priority 1 (explicit store), effectively discarding the CLI override.
Reproduction
opencode -m minimax-coding-plan/MiniMax-M2.7
The status bar initially shows MiniMax-M2.7
Send a message or wait for bootstrap to complete
The status bar and actual model routing switches to the default model (e.g., GPT-5.4)
User must press ESC, type /model, re-select the intended model, and resend the message
The CLI -m model lives in fallbackModel (Priority 3). The buggy createEffect (lines 401-417) promotes the agent's configured model to Priority 1:
createEffect(()=>{constvalue=agent.current()if(!value)returnif(value.model){if(isModelValid(value.model))model.set({// <-- WRITES TO modelStore.model[agent.name]providerID: value.model.providerID,modelID: value.model.modelID,})elsetoast.show({ ... })}})
Race condition timeline
TUI starts. sync.data.agent is initially [] (empty). agent.current() returns undefined. The createEffect guard if (!value) return prevents it from firing.
app.tsxonMount fires → local.model.set(cli_model, { recent: true }) → stores CLI model under modelStore.model[currentAgentName].
sync.bootstrap() (async) completes and populates sync.data.agent with the real agent list.
SolidJS reactivity: agents() memo changes → agent.current() re-evaluates → now returns the actual agent object.
The createEffect fires. If the current agent has a .model property (user-configured in opencode.json), it calls model.set(agent.model), which overwritesmodelStore.model[currentAgentName].
currentModel now returns the agent's model (Priority 1 wins) instead of the CLI model (Priority 3 fallback).
All subsequent TUI prompt submissions use the wrong model.
Why it varies
Default build/plan agents have no .model property by default → the createEffect's if (value.model) guard prevents overwrite → bug does NOT manifest.
User-configured agents (or when default_agent is set to a custom agent with a model) → the agent has .model → overwrite happens.
Timing-dependent: If bootstrap completes before the user sends the first message, even message 1 uses the wrong model. If bootstrap completes after, message 1 is correct but subsequent messages revert.
Related Issues
This is the same root cause affecting these linked issues:
Unifying invariant: Each agent in a session must have its own persistent selectedModel state, independent of ag.model, that survives first-message completion, mode switches, subagent dispatch, and session resume. Currently, the createEffect at local.tsx:401 systematically violates this by overwriting user-selected state with agent config on every reactive refresh.
Fix Direction
The createEffect at local.tsx:401-417 should NOT overwrite the per-agent model store when the current model was explicitly set by the user (via -m flag, /model command, or UI picker). Proposed approaches:
Guard with an "explicitly set" flag: Add a flag like modelStore.override[agentName] that is set to true when the user explicitly sets a model (via -m, /model, or UI). The createEffect checks this flag before overwriting:
Separate "agent default" vs "user selection" stores: Instead of a single modelStore.model, maintain two separate stores and adjust the priority chain in currentModel.
Remove the effect entirely: Rely on the existing priority chain where a.model is already at Priority 2 in currentModel. The effect is duplicative — it copies agent.model (Priority 2) into modelStore.model (Priority 1), which is what causes the Priority 1 override of the user's CLI choice.
Option 3 is the simplest and most likely correct fix. The createEffect exists so that when a user switches agents, the model automatically updates to the new agent's configured model. But this can be handled differently — for example, by clearing the per-agent store on agent switch rather than proactively writing the agent model into it.
Additional consideration: fallbackModel does not help
Even though fallbackModel checks args.model first (line 162), it is Priority 3 in the chain. The createEffect puts the agent model at Priority 1, making fallbackModel unreachable when the agent has a model.
Verification
To verify a fix:
Launch with -m flag specifying a model different from the agent's configured model
Verify the status bar shows the -m model before and after bootstrap
Send a message and confirm the model does not revert
Switch between agents and verify the -m model persists (or intentional agent-model switch behavior applies)
Activity
github-actions commentedon Apr 21, 2026
This issue might be a duplicate of existing issues. Please check:
/models), though the repro steps differ slightly. They may share the same root cause.coygeek commentedon Apr 27, 2026
Still not fixed
coygeek commentedon Apr 27, 2026
This is so annoying.
Steps to reproduce:
opencode -m minimax-coding-plan/MiniMax-M2.7To get this session back to normal, i now have to do the following workaround:
This is a major glitch.
coygeek commentedon Apr 27, 2026
Issue #23741: Model Reverts to Default After First Message When Launched with
-mSummary
When launching OpenCode with a specific model via
opencode -m <model>, the model shown in the status bar appears correct initially, but after the first message completes (or even before the first message, depending on bootstrap timing), it silently reverts to the user's default/agent-configured model.Root cause: A
createEffectinlocal.tsxsynchronizes the agent's configured model into the per-agent model store, which overwrites the CLI-moverride. The CLI model lives at Priority 3 (fallback), but the effect promotes the agent model to Priority 1 (explicit store), effectively discarding the CLI override.Reproduction
/model, re-select the intended model, and resend the messageRoot Cause Analysis
Key files and line numbers
packages/opencode/src/cli/cmd/tui/context/local.tsxcreateEffectthat overwrites CLI modelpackages/opencode/src/cli/cmd/tui/context/local.tsxcurrentModelmemo with three-tier prioritypackages/opencode/src/cli/cmd/tui/context/local.tsxfallbackModelmemo (includes CLIargs.model)packages/opencode/src/cli/cmd/tui/context/local.tsxmodel.set()— writes undermodelStore.model[agent.name]packages/opencode/src/cli/cmd/tui/app.tsxonMountwhere CLI-mmodel is stored vialocal.model.set()packages/opencode/src/cli/cmd/tui/context/local.tsxagent.current()— returnsagents().find(...) ?? agents().at(0)Detailed mechanism
The model resolution uses a three-tier priority chain in
currentModel()(lines 200-209):The CLI
-mmodel lives infallbackModel(Priority 3). The buggycreateEffect(lines 401-417) promotes the agent's configured model to Priority 1:Race condition timeline
TUI starts.
sync.data.agentis initially[](empty).agent.current()returnsundefined. ThecreateEffectguardif (!value) returnprevents it from firing.app.tsxonMountfires →local.model.set(cli_model, { recent: true })→ stores CLI model undermodelStore.model[currentAgentName].sync.bootstrap()(async) completes and populatessync.data.agentwith the real agent list.SolidJS reactivity:
agents()memo changes →agent.current()re-evaluates → now returns the actual agent object.The
createEffectfires. If the current agent has a.modelproperty (user-configured inopencode.json), it callsmodel.set(agent.model), which overwritesmodelStore.model[currentAgentName].currentModelnow returns the agent's model (Priority 1 wins) instead of the CLI model (Priority 3 fallback).All subsequent TUI prompt submissions use the wrong model.
Why it varies
build/planagents have no.modelproperty by default → thecreateEffect'sif (value.model)guard prevents overwrite → bug does NOT manifest.default_agentis set to a custom agent with a model) → the agent has.model→ overwrite happens.Related Issues
This is the same root cause affecting these linked issues:
-mflag model reverts after first messagecreateEffectoverwrites CLI model after bootstrapsync.data.agentrefresh post-message completionagent.current()change → effect firesmodelStore.model[agentName]key collisionUnifying invariant: Each agent in a session must have its own persistent
selectedModelstate, independent ofag.model, that survives first-message completion, mode switches, subagent dispatch, and session resume. Currently, thecreateEffectatlocal.tsx:401systematically violates this by overwriting user-selected state with agent config on every reactive refresh.Fix Direction
The
createEffectatlocal.tsx:401-417should NOT overwrite the per-agent model store when the current model was explicitly set by the user (via-mflag,/modelcommand, or UI picker). Proposed approaches:Guard with an "explicitly set" flag: Add a flag like
modelStore.override[agentName]that is set totruewhen the user explicitly sets a model (via-m,/model, or UI). ThecreateEffectchecks this flag before overwriting:Separate "agent default" vs "user selection" stores: Instead of a single
modelStore.model, maintain two separate stores and adjust the priority chain incurrentModel.Remove the effect entirely: Rely on the existing priority chain where
a.modelis already at Priority 2 incurrentModel. The effect is duplicative — it copiesagent.model(Priority 2) intomodelStore.model(Priority 1), which is what causes the Priority 1 override of the user's CLI choice.Option 3 is the simplest and most likely correct fix. The
createEffectexists so that when a user switches agents, the model automatically updates to the new agent's configured model. But this can be handled differently — for example, by clearing the per-agent store on agent switch rather than proactively writing the agent model into it.Additional consideration:
fallbackModeldoes not helpEven though
fallbackModelchecksargs.modelfirst (line 162), it is Priority 3 in the chain. ThecreateEffectputs the agent model at Priority 1, makingfallbackModelunreachable when the agent has a model.Verification
To verify a fix:
-mflag specifying a model different from the agent's configured model-mmodel before and after bootstrap-mmodel persists (or intentional agent-model switch behavior applies)coygeek commentedon May 23, 2026
Fixed