Repository navigation
Description
Summary
After updating to OpenCode 2.0.29, recent chat history is missing from the app. The one-shot V1→V2 data migration (kv.migration.v1-v2) had already been marked {"phase":"completed"} and never runs again, so sessions that were written to the legacy session / message / part tables after that migration are never imported into session_v2 / session_message. GET /api/experimental/migration/v1 still reports {"status":"completed"} even though 15 sessions exist in session with no corresponding session_v2 row.
Environment
- opencode version: 2.0.29 (desktop app
ai.opencode.desktop2.0.29; bundled CLI 2.0.29) - OS: Windows 11 (Windows_NT 10.0.26300.9550, win32 x64)
- Terminal: Warp (TERM=xterm-256color)
- Shell: cmd.exe
- Install/channel: latest (desktop, packaged) + pnpm-installed CLI 2.0.29
- Active plugins: none
Reproduction
- Install an OpenCode 2.x build so
~/.local/share/opencode/opencode.dbcontains the V2 tables and the V1→V2 data migration completes (kv.migration.v1-v2 = {"phase":"completed"}). - Run a pre-2.0 client (in my case the desktop app on versions 1.18.33–1.19.0) and create/resume sessions. Those rows are written to the legacy
session/message/parttables. - Update to OpenCode 2.0.29 and open the app.
- Observe: the sessions created in step 2 do not appear, and:
SELECT COUNT(*) FROM session= 71 vsSELECT COUNT(*) FROM session_v2= 59opencode api get /api/experimental/migration/v1→{"status":"completed"}
Expected Behavior
On startup (or when the status endpoint is queried), OpenCode should detect legacy session rows that have no session_v2 counterpart and import them, so upgrading to 2.0 never hides existing history.
Actual Behavior
Sessions that exist only in the legacy tables are silently orphaned and the app shows no history for them. The migration is effectively one-shot: when kv.migration.v1-v2 phase is completed, the migration returns early, and the status endpoint reports completed based on that flag without comparing session against session_v2.
Observed counts before the workaround:
session = 71
session_v2 = 59 (15 legacy sessions had no session_v2 row)
message = 4520
session_message = 2886
The 15 missing sessions all had version between 1.18.33 and 1.19.0. Sessions with version 1.18.15–1.18.32 (present when the migration first ran) were imported correctly, so the gap is specifically sessions created after the migration completed.
Additional Context
- No data was actually lost: all 15 sessions had full
messageandpartrows in the legacy tables. - Workaround that restored everything: set
kv.migration.v1-v2to{"phase":"sessions"}and restart the service. The startup migration re-ran (INSERT OR IGNOREintosession_v2plus a rebuild ofsession_messagefor each session), andsession_v2went 59 → 74 with 0 remaining un-imported sessions;migration.v1-v2then returned to{"phase":"completed"}. - The workaround also repaired one already-migrated session that had been truncated (
session_messagerows for it went from 9 to 102, matching its 99 legacy messages). - Suggestion: make the startup/status path compare the legacy
sessiontable againstsession_v2and re-import any missing ids, instead of trusting thephaseflag alone. The migration already supports resuming with{"phase":"sessions"}and usesINSERT OR IGNORE, so a re-check should be cheap. - Standalone database (SQLite):
~/.local/share/opencode/opencode.db.
Related Issues
- V1→V2 migration loses/hides history: corrupt-part migrator 500s, undecodable rows report no field detail, >9k-message imports 500 with empty body, project picker is a hidden shortcut #42671 — V1→V2 migration loses/hides history (corrupt rows, >9k-message sessions, hidden project picker). Different root cause: this report is only about the one-shot
phaseflag skipping legacy sessions created after the migration ran. - V1→V2 migration silently drops legacy messages missing required fields (agent/model/parentID) — old sessions show empty history #53971 — migration silently drops legacy messages missing required fields.
- v2: V1 sessions in non-git directories invisible after migration (legacy catch-all project) #50800 — V1 sessions in non-git directories invisible after migration (legacy catch-all project).
Activity
opencode-agent commentedon Oct 14, 2026
Thanks for the detailed report and the recovery steps. I think this is a duplicate of #50130. The V1→V2 import treats
migration.v1-v2 = {"phase":"completed"}as final, so sessions a 1.x client writes to the legacy tables afterwards are never imported, and the status endpoint keeps reportingcompleted.Possible duplicates and related issues, ordered by likelihood:
migration.v1-v2completes are never imported). Open PR fix(core): import V1 sessions created after migration completes #54272 targets it by re-importing only sessions created after the migration finished, so sessions deleted in V2 are not brought back.kvkey (rather than setting it to{"phase":"sessions"}as you did) wipes theeventtable, so anyone copying a workaround should be careful.globalproject).If you have anything new, please add it to #50130. The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
opencode-agent commentedon Oct 15, 2026
Closing this as a duplicate of #50130. There's been no reply saying how it differs. The cause is the same: once
migration.v1-v2is markedcompleted, sessions a 1.x client writes later are never imported intosession_v2. Please follow #50130 for updates; open PR #54272 is aimed at it. Thanks again for the counts and the{"phase":"sessions"}recovery steps. If you find something that #50130 doesn't cover, add it there or reply here and we can reopen.