Skip to content

sessions: POST /api/session/{id}/move stores a bogus path and hides the session from the project list #53454

Description

@vc

Summary

Moving a session into a target directory that is the target project's own root can store a bogus session.path, after which the session no longer appears in that project's session list. The move reports success (HTTP 204) with no error.

Environment

  • opencode version: 2.0.23 (npm @opencode/cli)
  • OS: Microsoft Windows 10 Pro, win32 x64
  • Shell: Cygwin bash; the git on PATH is Cygwin git (returns POSIX-style paths)
  • Plugins: none involved
  • Project is a git repository, sessions created on v2.0.23

Steps to reproduce

  1. Create a git repository D:/home/<user>/probe and start opencode in it once from a Cygwin shell, so the project row gets worktree / canonical in POSIX form (/home/<user>/probe) while sessions keep Windows-form directories.

  2. Create a session somewhere else (POST /api/session with directory=D:/work/a) and note its id.

  3. Move it to the project root:

    POST /api/session/<sessionID>/move
    {"directory":"D:/home/<user>/probe"}
    

    Response: 204 No Content.

  4. Ask the server the same question the TUI asks:

    GET /api/session?project=<projectID>&subpath
    

Actual Behavior

GET /api/session?project=<projectID>&subpath returns 0 sessions, and the moved session is not listed by opencode session list for that project, even though GET /api/session/<sessionID> returns it.

The stored row is:

id         | ses_...
project_id | <projectID>
directory  | D:/home/<user>/probe
path       | ../../../home/<user>/probe

Expected Behavior

The target directory is the project's own root, so path must be the empty string, and the session must show up at the project root subpath:

GET /api/session?project=<projectID>&subpath   ->  1 session
path                                          ->  ''

Why

session.path is meant to hold the session directory relative to the project root ('' means the project root), and the project session list filters on exactly that value via the subpath query parameter. The move handler appears to derive it with something equivalent to path.relative(project.worktree, directory) without normalizing path styles. Here the project root is stored POSIX (/home/<user>/probe) while the requested directory is Windows (D:/home/<user>/probe), so the relative path is computed across two unrelated roots and comes out as ../../../home/<user>/probe.

The same normalization gap was observed once on session creation rather than on move: a session created with a directory that did not resolve to a known project fell back to the global pseudo-project (worktree = '/') and received path = '../../home/<user>' instead of ''.

Two related observations, in case they are of interest to the maintainers:

  • project.worktree itself stores whatever git discovery returns, so a project discovered from a Cygwin shell keeps a POSIX root while every session directory stays Windows-form. All other projects on the machine are stored Windows-form, so this also means the same physical directory can be represented in two styles.
  • The session move endpoint (POST /api/session/{sessionID}/move) is not mentioned in the public docs, although the /move TUI command uses it.

Impact

Silent loss of visibility: the move succeeds, the session disappears from the sidebar and from opencode session list for the target project, and neither reopening the project nor repeating the move brings it back — the row has to be corrected in the database (path = ''). This is the same failure mode that makes pre-migration sessions invisible.

Suggested fix

Normalize the project root and the target directory to a single form before computing the relative path, and short-circuit to '' when both resolve to the same directory. Possibly also normalize project.worktree to the platform's native form when it is stored.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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