Repository navigation
Description
Summary
In the desktop app, sessions from unrelated folders are merged into one shared project when those folders do not have an independently resolvable project identity (they are not a git repo, or are a git repo with no commits yet / unborn HEAD). Selecting one folder in the sidebar shows sessions created in other folders too.
Environment
- opencode version: 2.0.26
- OS: Darwin 27.2.0 (darwin arm64)
- Terminal: Unavailable: terminal environment variables are not set (observed in the desktop app)
- Shell: /bin/zsh
- Install/channel: latest
- Active plugins: None found in config
Reproduction
- Create two or more separate folders that are either (a) not a git repository, or (b) a git repository created with
git initbut with no commits (unbornHEAD). - Open each folder as its own project in the desktop app and start/run a session in each.
- In the sidebar, select one of those folders and look at its session list.
Expected Behavior
The session list for a selected project/folder should only contain sessions that belong to that folder.
Actual Behavior
The session list contains sessions from all folders that lack an independent project identity, i.e. sessions from unrelated folders are mixed into the selected one. It is intermittent in practice only because most folders are real git repositories with commits (those get their own stable project id and stay isolated); the problem appears whenever such "identity-less" folders are opened together.
Additional Context
Root cause appears to be that OpenCode cannot derive a project id for a folder when it is not a VCS repo, or is a repo with an unborn HEAD, and falls back to a single shared catch-all project (project_id = "global"). Because the session list is filtered by project_id (with no fallback to directory), every folder that maps to global shares one session pool.
Evidence from local storage at ~/.local/share/opencode/opencode.db (names redacted):
1. One global bucket holds far more sessions than any real project, spanning many distinct directories
session_v2 grouped by project_id (top rows):
global 156
<hash-A> 38
<hash-B> 35
...
2. The worktree table maps several different directories to the same project_id = global
project_id | directory
global | <home>/.../folderA
global | <home>/.../folderB
global | <home>/.../folderC
3. Sessions shown under the wrong project all carry project_id = global while their directory differs
title | project_id | directory
<session-in-folderA> | global | <home>/.../folderA
<session-in-folderB> | global | <home>/.../folderB
<session-in-folderC> | global | <home>/.../folderC
4. Correlation: folders that fall back to global have no commits; folders with their own project id have commits
directory | git toplevel | HEAD commits | resulting project_id
folderA | yes | unborn/fatal | global
folderB | yes | unborn/fatal | global
folderC | no | n/a | global
repoX | yes | 30 | <unique hash>
repoY | yes | 11 | <unique hash>
Workaround
Give each affected folder a real git repository with at least one commit:
cd <folder> && git add -A && git commit -m "init"After that OpenCode assigns it a unique project id and its sessions no longer mix. For non-repo folders, git init followed by one commit achieves the same.
Suggested fix
When a folder has no resolvable project identity, either generate a per-directory project id, or fall back to filtering sessions by directory instead of collapsing everything into a single global project.
Activity
opencode-agent commentedon Oct 13, 2026
Thanks for the detailed report. I can reproduce this on 2.0.26, and it still happens on the latest
dev(65f8907).Steps (the script below does them):
git initin each, with no commits.opencode session listin either folder.Both sessions show up in both lists, each with project id
global.One difference from your report: on v2, a plain folder with no repository gets its own project id and stays separate in my test. The plain folders under
globalin your database were most likely imported from v1, which is tracked in #50551 and #55081. The empty-repo case is still a real problem on v2.Related:
globalproject's worktreeUntil this is fixed, your workaround of making one commit in each such repo gives it its own project.
Reproduction script (repro.sh)
Run it:
bash repro.shDante-dan commentedon Oct 14, 2026
I’m taking the CLI reproduction described above:
session listcurrently filters only by project ID. I’ll use the resolved directory when the project isglobal, matching the existing TUI fallback, and preserve project-wide listing for repositories with their own identity. This does not change project identity or the session-move behavior in #50979.ejvallej commentedon Nov 2, 2026
Confirming the unborn-
HEAD→project.id = "global"fallback on the current release, and adding one symptom that is arguably worse than the session mixing, plus the id-derivation detail.Version differs, same cause
2.2.5— Desktop, bundled CLI2.2.5(@opencode/desktop), Linux 7.2.9-1-MANJARO x86_64, Wayland/KDE, Electron 44.10.0, system install at/usr/lib/opencode-desktop, pluginopencode-mem@latest.1.18.16is also onPATH; not involved.Additional symptom: Desktop lands on
/, not on the chosen folderThe
globalproject's worktree is/. So a user opening a folder in a zero-commit repo does not merely see other folders' sessions merged — the app opens the root project and shows the whole/. Nothing tells the user why; it looks like the folder was opened wrong. A single affected folder is enough, so this reproduces without setting up a second folder.No row is inserted into
project; theglobalrow keepsworktree = /andvcs = git, and every location boot then logs:That
worktree discovery failedwarning repeats fordirectory=/on every boot, becauseglobalclaimsvcs = gitat the filesystem root. Worth a separate look: a catch-all project probably should not carryvcs = gitat/.Control cases (2.2.5, same service)
.gitproject.idgit initonlyglobalgit init+ one commit.git)global,canonical= repo rootNote the asymmetry: a plain directory does get its own id, so it is specifically the unborn-
HEADbranch of the VCS path that falls through to the global project.Project id appears to be derived from the initial commit (possible collision)
While fixing my folders I hit this: two independent repos whose initial commits were identical — same empty tree, same author/date/message, trivially produced by running
git commit --allow-empty -m "init"twice within the same second in two different repos — resolved to the same project id, and only one row existed inproject. Amending one commit to a distinct message gave it a distinct id.So project identity for git repos seems to come from the initial commit object, with no path component. That means two unrelated repositories with an identical first commit can collide and share sessions even though both have commits. Including the canonical path in the identity would remove that.
Workaround that works
Give the repo one commit, or drop the unused
.git, then reload:Suggested fix direction
Since an unborn
HEADis a normal state for a freshly initialized repo, that branch should still mint a project identity (path-derived) instead of falling through toglobal; andglobalshould not be a git worktree at/. Failing that, the Desktop should at least refuse to open the folder with an explicit error rather than silently switching the user to/.