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
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:
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.worktree
session.project_id
session.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 UI
canonicalPath: resolved real path, used for identity/matching
- Avoid direct string path matching in Desktop session filtering when a stable
project_id or 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.
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
~/.local/share/opencode/opencode.db~/.config/ai.opencode.desktop/opencode.global.datSetup
Assume this directory layout:
/workspaceis a symlink to/home/user/workspace.The project is opened in opencode Desktop using the symlink path:
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:
The session records exist and are valid, but they are associated with the project whose
worktreeis the resolved path, not the symlink path currently selected in Desktop.As a result, when selecting
/workspace/projectin Desktop, the session list is empty and the UI shows: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.worktreesession.project_idsession.directoryActual behavior
The same physical project can be split into two identities:
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:
And sessions like:
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:
Suggested fix
Use a single stable project identity across Desktop and backend.
Possible approaches:
displayPath: path opened by the user, used for UIcanonicalPath: resolved real path, used for identity/matchingproject_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.