Repository navigation
migration: V1 sessions in non-git directories are unreachable in the V2 session list #56312
Description
Summary
Sessions created by V1 in a non-git directory are stored with project_id = 'global'. The V1→V2 data migration copies those rows verbatim, but V2 assigns every directory a real project id, so nothing ever matches global again. opencode session list (documented as "top-level sessions in the current project") therefore never shows them. The sessions are fully intact in the database, but they are unreachable from the UI/CLI without a manual re-tag.
Environment
- opencode version: 2.0.32
- OS: Windows 11,
Windows_NT 10.0.26200(win32 x64) - Terminal:
TERM=xterm-256color,TERM_PROGRAMunset - Shell:
C:\WINDOWS\system32\cmd.exe(invoked through PowerShell 5.1) - Install/channel:
latestrelease, background service at127.0.0.1 - Active plugins: none found (
~/.config/opencode/opencode.jsonhas noplugins; no local plugin dirs)
Reproduction
- On V1, start opencode in a directory that is not a git repository and create a few sessions. (V1 records these with
project_id='global'; confirmed in the V1 log:projectID=global directory=....) - Upgrade to V2. V1 and V2 share the same data directory (
~/.local/share/opencode), so the existingopencode.dbis reused. - Let the automatic v1→v2 data migration complete. It reports success (
kvtable:migration.v1-v2 = {"phase":"completed"}). - Run
opencode session listin that same non-git directory.
Expected Behavior
The sessions created in step 1 are listed, as they were in V1.
Actual Behavior
opencode session list returns only sessions created after the V2 upgrade — in this case 1 session, where V1 had 63 for the same directory.
The data is present and readable by id:
session(V1 table): 220 rows;session_v2(V2 table): 221 rows.- 220 session ids exist in both tables; 0 rows are V1-only. No data loss.
- 220 of the
session_v2rows carryproject_id = 'global'; the single post-upgrade row carries a real project id (a sha1-like hash of the worktree, present in theprojecttable withworktree = <the directory>). opencode session export <id>works on an orphaned session (returned ~1.7 MB of JSON), so the rows are fine — only project scoping hides them.
Moving one orphaned session with the session_move API (directory = its own directory) rewrote session_v2.project_id from global to the real project id, and the session immediately appeared in opencode session list. So the recovery path exists, but it must be applied per session; there is no migration-time or bulk path.
Additional Context
- Affected material in this report instance: 220 migrated sessions spread over 7 non-git directories — 146 in one directory, 63 in the home directory, 8 across two app directories, and 3 single-session directories.
- Root cause is a mismatch of project scoping between majors, not a serialization problem:
- V1: non-git location ⇒ sentinel project id
global. - V2: every location ⇒ real project id derived from the worktree.
- Migrator: copies session rows as-is, so the sentinel survives into a version that can no longer resolve it.
- V1: non-git location ⇒ sentinel project id
~/.local/share/opencode/storage/is a vestigial V1 file store (1 session file, last written months before the upgrade); all sessions live inopencode.db(SQLite, WAL). Themigrationtable and__drizzle_migrationsshow the upgrade ran cleanly, so this is not a failed-migration symptom.- Suggested directions (whichever fits the project's intent): re-tag migrated rows whose
project_idno longer resolves to a known project during V1→V2 migration; or special-case the legacyglobalproject when listing sessions; or offer a bulk re-tag (e.g.opencode session move --all --project current). - Workaround used in the meantime: per-session
session_moveto the target directory, keeping each session in its own directory's project.
Activity
opencode-agent commentedon Oct 17, 2026
Thanks for the detailed report and the per-directory numbers! I think this is a duplicate of #49827: after the V1→V2 migration, sessions that V1 created in non-git directories keep
project_id = 'global', V2 creates a separate project for each of those directories, and the project-scoped session list hides them. The data itself is intact.These are the possible duplicates and closely related issues, ordered by likelihood:
globalsessions from non-git directories are hidden after upgrading, with confirmations up to 2.0.27.globalsessions stay unattributed. The open fix PR fix(core): attribute migrated V1 sessions to the project of their directory #51935 links this issue.session.pathmust also be normalized, not onlyproject_id, for the sessions to show up again.Until that's resolved, the per-session
session moveyou already used is the known workaround. #49827 and #50551 have more notes on it, including thepathcaveat.The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different. Please follow #49827 for updates.
opencode-agent commentedon Oct 18, 2026
We haven't heard back, so I'm closing this as a duplicate of #49827. After the V1→V2 migration, sessions from non-git directories keep
project_id = 'global', and V2 creates a separate project for each of those directories, so the project-scoped session list hides them. Your data is intact.Please follow #49827 and the open fix PR #51935 for updates. Until then, the per-session
session moveyou already used is the workaround; #50551 explains whysession.pathmay need fixing too. If your case turns out to be different, reply here and we can reopen.