Skip to content

Resuming a session after switching the global default model still uses the old recorded model (session.model) — blocks continuation when old model is unavailable #45204

Closed as not planned

Description

@boyingliu01

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:

  1. session.model (the stored old model) — always used if present
  2. last user message's recorded model — fallback, still the old model
  3. provider.defaultModel() (reads opencode.json model) — 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

  1. Configure global "model": "providerA/model-old" in opencode.json.
  2. Start a session under providerA/model-old and do some work.
  3. Switch global "model" to "providerB/model-new" (e.g. because providerA quota/API key expired).
  4. Resume the old session (/sessions → pick it, or opencode --continue).
  5. Observe: the session still uses providerA/model-old and fails with an API error if that model is unavailable. The task cannot continue under providerB/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

Operating System

WSL2 / Ubuntu (Linux)

Terminal

Windows Terminal (via WSL)

Activity

  1. Tarquinen commented on Oct 20, 2026

    @Tarquinen
    Member

    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 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions