Description
Description
opencode Desktop appears to mishandle projects opened through symlink paths.
When a project is opened from a symlinked path, Desktop keeps the symlink path in its project list/state, but sessions are stored in the backend database under the resolved real path. Because the UI filters sessions by the currently selected project identity/path, existing sessions are not shown even though they exist in the database.
Environment
- opencode Desktop version: 1.15.13
- OS: Linux
- Install type: Desktop app
- Relevant data locations:
- Session DB:
~/.local/share/opencode/opencode.db - Desktop state:
~/.config/ai.opencode.desktop/opencode.global.dat
- Session DB:
Setup
Assume this directory layout:
/workspace -> /home/user/workspace
/workspace/project
/home/user/workspace/project
/workspace is a symlink to /home/user/workspace.
The project is opened in opencode Desktop using the symlink path:
/workspace/project
What happens
Desktop stores the project entry using the symlink path:
{
"worktree": "/workspace/project"
}However, the backend SQLite database stores the project and sessions using the resolved real path:
project.worktree = /home/user/workspace/project
session.directory = /home/user/workspace/project
The session records exist and are valid, but they are associated with the project whose worktree is the resolved path, not the symlink path currently selected in Desktop.
As a result, when selecting /workspace/project in Desktop, the session list is empty and the UI shows:
No sessions found
Start a new session for this project
Expected behavior
Sessions created for a project should be visible regardless of whether the project was opened through a symlink path or its resolved real path.
At minimum, Desktop and the backend should use the same normalized project identity for:
- project list entries
project.worktreesession.project_idsession.directory- last opened/restored session state
Actual behavior
The same physical project can be split into two identities:
/workspace/project
/home/user/workspace/project
Desktop selects one path, while the session database stores another, causing the UI to filter out existing sessions.
Evidence
The database contained a project row like:
project.id = <hash>
project.worktree = /home/user/workspace/project
And sessions like:
session.project_id = <hash>
session.directory = /home/user/workspace/project
session.title = Quick check-in
But Desktop state contained the project list entry:
{
"worktree": "/workspace/project",
"expanded": true
}After manually making the database project/session paths consistent with the Desktop symlink path, the sessions became visible again.
Likely root cause
There seems to be inconsistent path normalization between Desktop and the backend/sidecar:
- Desktop project state preserves the user-opened symlink path.
- Backend project/session creation resolves the path to the real path.
- Session lookup/filtering then relies on direct path/project identity matching without accounting for symlink equivalence.
Suggested fix
Use a single stable project identity across Desktop and backend.
Possible approaches:
- Always canonicalize paths everywhere before storing or matching.
- Preserve the user-facing display path, but store and match by canonical path.
- Store both:
displayPath: path opened by the user, used for UIcanonicalPath: resolved real path, used for identity/matching
- Avoid direct string path matching in Desktop session filtering when a stable
project_idor canonical path can be used.
Workaround
A manual workaround is to make the Desktop project state and SQLite project/session records use the same path form, either all symlink paths or all resolved real paths.
This is fragile because future session creation may again normalize paths differently.
Activity
github-actions commentedon Jun 1, 2026
This issue might be a duplicate of existing issues. Please check:
opencode.global.datstate file involvedInstance.containsPath()compares mixed canonical/non-canonical paths — related inconsistency between symlink paths and resolved paths in the backendgithub-actions commentedon Aug 1, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.