Repository navigation
OpenCode agent fails at startup: restore passes a Claude session id to opencode --session #765
Description
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
- Start an agent as Claude and let it run one turn.
- Switch the same agent to OpenCode with the engine picker.
- 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
sessionIdandsessionHistorysurvive a provider change. - Startup restore spawns every agent with
resume: true. chooseResumeSessionattaches 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:
fdb9d430fix(resume):sessionIdFits(provider, sid)insrc/shared/resumeStore.tsrequires an OpenCode id to start withses_.chooseResumeSessionskips an id of another shape, still resumes an older OpenCode id, and starts fresh withresumeNotFoundwhen none is left.src/main/index.tslogs the skipped ids.13142bf4fix(hive): a spawn that names a different provider than the registry entry drops the recordedsessionIdandsessionHistory. 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