Skip to content

OpenCode agent fails at startup: restore passes a Claude session id to opencode --session #765

Open

Description

@gpinkham

What happens

After an agent is switched from Claude to OpenCode, the next app start fails to bring it up. Startup restore launches opencode --session <id> with a UUID, and OpenCode refuses it because its session ids start with ses_. The terminal tab shows the same UUID as the agent's session.

Steps

  1. Start an agent as Claude and let it run one turn.
  2. Switch the same agent to OpenCode with the engine picker.
  3. Quit and relaunch the app.

Expected

The agent resumes its OpenCode session, or starts a fresh one if it has none.

Actual

opencode --session <claude uuid> is launched and OpenCode exits with an invalid session id error.

Cause

  • The registry upsert at spawn spreads the previous entry, so sessionId and sessionHistory survive a provider change.
  • Startup restore spawns every agent with resume: true.
  • chooseResumeSession attaches the newest recorded id unchecked when the provider has no session store spec, and OpenCode has none (its sessions are in SQLite).

Seen on 0.5.7. Main (0.4.6) already has startup restore with resume and a recorded session id, but no OpenCode resume flag and none of the 0.5.x resume selection code this patch changes (src/shared/resumeStore.ts), so main does not show this OpenCode failure.

Same risk elsewhere

Gemini, Antigravity, Crush and Copilot also attach recorded ids unchecked, so an id left from another provider would be passed to them too. The same is true of any provider an agent switches to.

Proposed patch

Branch: https://github.com/gpinkham/munder-difflin/tree/fix/opencode-resume-session-id

Two commits on top of the 0.5.4 source:

  • fdb9d430 fix(resume): sessionIdFits(provider, sid) in src/shared/resumeStore.ts requires an OpenCode id to start with ses_. chooseResumeSession skips an id of another shape, still resumes an older OpenCode id, and starts fresh with resumeNotFound when none is left. src/main/index.ts logs the skipped ids.
  • 13142bf4 fix(hive): a spawn that names a different provider than the registry entry drops the recorded sessionId and sessionHistory. An entry with no provider counts as Claude, and a spawn that names no provider changes nothing.

Both are needed. The second stops new cases. The first fixes an agent switched before the patch, whose entry already says opencode and still holds the Claude ids.

Tests: test/opencode-provider-switch-session.test.cjs (new) and test/v053-resume-all-providers.test.cjs (one new test, one source check updated). Without each change, 2 tests fail.

Not covered: Gemini, Antigravity, Crush and Copilot entries switched before the patch would still attach their leftover ids on each restart. A one time cleanup or a provider tag on each recorded id would close that.

The registry half (13142bf4) also applies to main: main keeps sessionId across a provider switch too, and attaches it unchecked for providers with a resume flag, for example Crush or Gemini.

Happy to open a PR once a 0.5.x branch is public, since main does not have the 0.5.x resume code this patch changes.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    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