Skip to content

Desktop fails to show sessions when project is opened through a symlink path #30260

Description

@luolong47

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:

/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.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:

  1. Always canonicalize paths everywhere before storing or matching.
  2. Preserve the user-facing display path, but store and match by canonical path.
  3. Store both:
    • displayPath: path opened by the user, used for UI
    • canonicalPath: resolved real path, used for identity/matching
  4. 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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions