Repository navigation
Description
Summary
The V1→V2 session migration is a one-time import: after it completes, any sessions and messages created by a still-installed V1 app (e.g. the V1 desktop app) are never imported, so they are invisible to V2. This makes restored desktop tabs point at sessions the V2 server cannot find ("This session cannot be found / this tab points to a session that no longer exists on this server"), and it silently truncates the transcripts of sessions that were migrated before being continued in V1.
Environment
- opencode version: 2.1.4 (V2 server/desktop; bundled CLI 2.1.4). Previously V1 desktop app running server v1.19.4.
- OS: Windows_NT 10.0.26200 (win32 x64)
- Terminal: N/A — OpenCode desktop app
- Shell: cmd.exe
- Install/channel: desktop app,
latestchannel - Active plugins: none found in config
Reproduction
- Have the V1 desktop app installed (its server writes the legacy
session,message,parttables in~/.local/share/opencode/opencode.db). Also start a V2 binary (CLI 2.1.4) once — the one-time migration runs and marks itself completed (kvkeymigration.v1-v2={"phase":"completed"}). - Keep using the V1 desktop app for a while: create new sessions and continue old ones. These writes go to the legacy tables only.
- Uninstall the V1 desktop and install the V2 desktop (2.1.4). The V2 server serves sessions only from the new
session_v2/session_messagetables. - On first launch the desktop restores its previous tab layout (kept in
%APPDATA%\ai.opencode.desktop, which the uninstaller does not remove). Tabs pointing at V1-created sessions fail with "This session cannot be found — this tab points to a session that no longer exists on this server".
Expected Behavior
V2 should surface sessions/messages written by V1 after the one-time import — e.g. re-run the legacy import incrementally at server start (import legacy rows missing from session_v2/session_message), or merge both tables when serving. The V1→V2 migration guide states non-API V1 behavior is intended to remain compatible; sessions created right before upgrading are effectively lost from the UI otherwise.
Actual Behavior
Observed on this machine (data was recovered manually; nothing was actually deleted):
- 5 sessions created by the V1 app after the import had completed were present in the legacy
sessiontable (with all messages inmessage/part) but absent fromsession_v2, soGET /api/sessiondid not list them andGET /api/session/{id}404'd. Sizes: 712, 104, 80, 18 and 2 messages respectively (916 total). - 1 already-migrated session continued in V1 lost visibility of ~380 messages appended after the import: the API served only its first 30 messages even though the legacy tables held ~410.
- The kv table contains
migration.v1-v2={"phase":"completed"}with a timestamp between the two batches, which is why the later batch was never imported.
Workaround used (documenting for others hitting this): copy the legacy session rows into session_v2 (NULL for v2-only columns, resume_attempts=0), and transform message+part rows into session_message (role → type, legacy order → seq, state.output → state.content[0].text, state.error string → state.error = {type: "tool.execution", message}, callID→id, tool→name, part-level metadata→providerState, drop step-start/step-finish/patch parts but keep snapshot.start/snapshot.end/snapshot.files, drop title/time from state, meta.variant → model.variant defaulting to default). This reproduces what the one-time importer produces (verified byte-identical against all 650 messages it had already imported on this machine).
Additional Context
- The V1 desktop and V2 desktop share the same data directory (
~/.local/share/opencode/), includingopencode.log, so the two server versions log side by side; V1 runs loggedversion=1.19.4on session creation while V2 sessions logversion=2.1.4. - Uninstalling the V1 desktop does not clear
%APPDATA%\ai.opencode.desktop(tab/window state), which is why stale tabs referencing now-invisible sessions surface immediately after upgrading. - Recovery was verified end-to-end via the V2 API (all 916 messages served and rendered correctly, including tool parts, reasoning, snapshots, tokens, errored and aborted tools).
- Frequency: deterministic for any V1 session/message created after the one-time import has run.
Activity
opencode-agent commentedon Oct 25, 2026
Thanks for the very thorough report and for writing down the manual recovery steps.
I think this is a duplicate of #50130: the V1→V2 import runs only once, so sessions a V1 client creates after
migration.v1-v2is markedcompletednever get imported, and desktop tabs pointing at them show "no longer exists on this server". The truncated transcript for the session you kept using in V1 is tracked separately in #57000.Possible duplicates and related issues, ordered by likelihood:
migration.v1-v2completes are never imported (404, stale desktop tabs). Same problem as your 5 missing sessions.The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different. Your field-mapping notes and the byte-identical check against the importer's output would be useful in #50130 and #57000.
opencode-agent commentedon Oct 26, 2026
We didn't hear back, so I'm closing this as a duplicate of #50130. It covers V1 sessions created after
migration.v1-v2was markedcompleted, which are never imported. The missing messages in your already-migrated session are tracked in #57000, and open PR #54272 would import V1 sessions created after the migration finished.Please follow those issues for updates. Your field mappings and the byte-identical check against the importer's output would help there, so consider adding them. If your problem turns out to be different, reply here and we can reopen this.