Repository navigation
Description
Description
When I switch the global default model in opencode.json (e.g. from xiaomi/mimo-v2.5-pro to whalecloud/g-deepseek-v4-flash) and then resume an existing session that was created under the old model, opencode still uses the old recorded model for that session instead of the new global default.
This becomes a hard blocker when the old model is no longer available (quota exhausted / invalid API key): the resumed session immediately fails with AI_APICallError and the in-flight task cannot continue under the new model.
Root cause is in packages/opencode/src/session/prompt.ts, the currentModel helper:
const currentModel = Effect.fnUntraced(function* (sessionID) {
const current = yield* db
.select({ model: SessionTable.model })
.from(SessionTable)
.where(eq(SessionTable.id, sessionID))
.get()
if (current?.model) {
// 1. session.model (stored old model) wins — never falls back to global default
return { providerID: ..., modelID: ... }
}
const match = yield* sessions
.findMessage(sessionID, (m) => m.info.role === "user" && !!m.info.model)
if (Option.isSome(match) && match.value.info.role === "user") return match.value.info.model // 2. last user message model
return yield* provider.defaultModel().pipe(Effect.orDie) // 3. global default — only when neither exists
})So the selection order on resume is:
session.model(the stored old model) — always used if present- last user message's recorded model — fallback, still the old model
provider.defaultModel()(readsopencode.jsonmodel) — only reached when neither 1 nor 2 exists
Since every session that ever ran stores a session.model, resuming after a model switch always keeps the old model and never falls back to the new global default.
Plugins
oh-my-openagent (which manages subagent model config via ~/.omo/omo.jsonc)
OpenCode version
1.18.23
Steps to reproduce
- Configure global
"model": "providerA/model-old"inopencode.json. - Start a session under
providerA/model-oldand do some work. - Switch global
"model"to"providerB/model-new"(e.g. because providerA quota/API key expired). - Resume the old session (
/sessions→ pick it, oropencode --continue). - Observe: the session still uses
providerA/model-oldand fails with an API error if that model is unavailable. The task cannot continue underproviderB/model-new.
Expected behavior
A session resumed after a global model switch should be able to continue under the new default model, especially when the previously-recorded model is no longer available. At minimum there should be a way to make a stuck session fall back to the current default, and a clear signal when the recorded model is stale/unavailable.
Suggested direction (similar to the proposal in #43179): distinguish a session model that is following the default from one pinned by the user. When a recorded model is missing/unauthorized and it wasn't explicitly pinned, fall back to the current global default instead of hard-failing.
Related issues
- Last command model is selected after exit and resume #38165 — same root cause (
session.modeloverwritten / stale on resume), triggered by a command model - [BUG]: Primary-agent switches silently keep the previous agent's model in V2 #43179 — session model silently preserved on agent switch (V2)
- stale synthetic continuation rows can overwrite the session model #33044 — stale continuation rows can overwrite the session model
- [OpenCode v1.16.42] task 工具派发 subagent 时不使用 agent.md 配置的 model,继承父 session model #44680 — subagent sessions inherit parent session model instead of agent-configured model
Operating System
WSL2 / Ubuntu (Linux)
Terminal
Windows Terminal (via WSL)
Activity
Tarquinen commentedon Oct 20, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊