Repository navigation
session: move keeps the source project, so the session appears in both workspaces #53830
Description
Description
Summary
Moving a session to a directory that belongs to a different project does not reassign the session's project. The session keeps the source project_id, the destination directory is added as another worktree of the source project, and the session is then returned by project-scoped listings — so in the desktop GUI the same session shows up under both the old and the new workspace.
Environment
- opencode version: 2.0.24
- OS: Windows 10.0.26300.9457 (win32 x64)
- Terminal: xterm-256color (TERM_PROGRAM/COLORTERM unset)
- Shell: cmd.exe
- Install/channel: npm global
@opencode/cli@2.0.24(latest) - Active plugins: none
Reproduction
- Create two independent git repos:
A = %TEMP%\opencode\movetestA,B = %TEMP%\opencode\movetestB(eachgit init+ one commit). - From
A, create a session:opencode run "reply with the single word: pong". The new session'ssession_v2.project_idis the project forA. - Move it to
B:POST /api/session/{id}/movewith{"destination":{"directory":".../movetestB"}}(also reproducible through the built-in session-move tool, and/movewhere the command is available). - Inspect the database and the session-list API (details in Additional Context).
Expected Behavior
The session should be associated with the destination project (the project for B). At minimum, the destination directory should not become a worktree of the source project. The session should appear only in the new workspace.
Actual Behavior
session_v2.project_idremains the source project forA; onlysession_v2.directorychanges tomovetestB.- The source project gains a second
worktreerow formovetestB. - The
location-switchedmessage records the sourceprojectIDfor both the previous and the new location. GET /api/session?project=<A>returns the session;GET /api/session?directory=movetestAexcludes it;GET /api/session?directory=movetestBincludes it.- In the desktop GUI the same session is listed under both the old and the new workspace.
Additional Context
Evidence after the move:
session_v2: { id: "ses_...", project_id: "<projectA>", directory: ".../movetestB" }
worktree (project "<projectA>"):
- ".../movetestA"
- ".../movetestB"
session_message type="location-switched":
{
"projectID": "<projectA>",
"previous": { "location": { "directory": ".../movetestA" }, "projectID": "<projectA>" },
"location": { "directory": ".../movetestB" }, "projectID": "<projectA>"
}
API membership (searched the moved session id in each response):
GET /api/session?project=<projectA> -> PRESENT
GET /api/session?directory=.../movetestA -> absent
GET /api/session?directory=.../movetestB -> PRESENT
Because both directories now resolve to the same project (through worktree), any project/worktree-scoped view lists the session for each directory. Real-world case: two non-git directories under the global project — every global session is listed under both.
Frequency: consistent (reproduced 100%).
Workaround: restart the desktop app, or close and reopen the project to force a refresh; the underlying association still spans both directories.
Related: #34359 (TUI migration umbrella), #39614 (V2 UI does not support workspaces), #31026 (preserve directory context after moving a session), #35012 (/move does not work).
Plugins
No response
OpenCode version
2.0.24
Steps to reproduce
- Create two independent git repos:
A = %TEMP%\opencode\movetestA,B = %TEMP%\opencode\movetestB(eachgit init+ one commit). - From
A, create a session:opencode run "reply with the single word: pong". The new session'ssession_v2.project_idis the project forA. - Move it to
B:POST /api/session/{id}/movewith{"destination":{"directory":".../movetestB"}}(also reproducible through the built-in session-move tool, and/movewhere the command is available). - Inspect the database and the session-list API (details in Additional Context).
Screenshot and/or share link
No response
Operating System
10.0.26300.9457 (win32 x64)
Terminal
xterm-256color (TERM_PROGRAM/COLORTERM unset), Windows Terminal
Activity
opencode-agent commentedon Oct 8, 2026
Thanks for the detailed report. I tried this on 2.0.24 (Linux) but couldn't reproduce it with two independent repos: I created a session in
A, moved it withPOST /api/session/{id}/movetoB, and the session'sproject_idbecame B's project.Bwas registered under its own project and thelocation-switchedmessage recorded A as the previous project and B as the new one.I could only get exactly your database state (the same
project_id, withBadded as a second worktree of A's project) when both repos had the same root commit. OpenCode identifies a git project by its root commit, so clones and worktrees of one repo share a project. If two test repos are created by a script within the same second, with the same author and an empty or identical first commit, they get the same commit SHA, and OpenCode then treats them as one project.Could you check whether this applies to your test repos? In each one, run:
If the SHAs are identical, that explains what you saw. If they differ and the move still keeps project A, please share both SHAs and the
projectandworktreerows for those directories so we can look further.Your non-git case (two directories that both resolve to the
globalproject) comes from that shared-project resolution, not from the move itself. It is closely related to #50979.You can reply here, or edit the issue and then leave a comment saying you've updated it.
cncloudli commentedon Oct 8, 2026
yes, I've re-tried this, the true issue is 50979
opencode-agent commentedon Oct 8, 2026
Thanks for re-testing and confirming. Since the problem you're seeing is #50979 (a session moved between directories that resolve to the same shared project, such as
global, stays in that project and the directories end up listing each other's sessions), we'll treat this issue as a duplicate of it. Please follow #50979 for updates, and add any extra details there, such as your non-git case underglobalon Windows.The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem differs from #50979.
opencode-agent commentedon Oct 9, 2026
Closing this as a duplicate of #50979, which you confirmed is the real problem: a session moved between directories that resolve to the same shared project (such as
global) stays in that project, so both directories list it. Please follow #50979 for updates, and add any details there, such as your Windows non-git case. If you find something that #50979 doesn't cover, feel free to open a new issue with the steps. Thanks for testing this so carefully!