Skip to content

Web: Sidebar session list hides worktree/sandbox sessions after 1.2.6 upgrade (filters to current directory only) #14082

Closed

Description

@benoitheinrich

Description

After upgrading OpenCode from 1.2.5 -> 1.2.6, the Web UI sidebar session list no longer shows sessions from git worktrees / sandboxes for a repo. The sessions still exist and are visible in the TUI/CLI, and the web server API can return them, but the Web UI sidebar only shows sessions for the current directory (typically the main repo root) and hides sessions whose session.directory is a different worktree/sandbox directory.
This looks like a Web UI scoping/filtering regression (or missing “show sessions across sandboxes” behavior) introduced in 1.2.6. It worked as expected for me on 1.2.5.

Plugins

oh-my-opencode 3.7.3

OpenCode version

1.2.6
Note that it's working by downgrading to 1.2.5

Steps to reproduce

  1. Have a git repo with multiple worktrees, e.g.
    • main repo: /home/USER/dev/REPO
    • worktrees: /home/USER/dev/_wt/REPO-*
  2. Start the Web UI from a neutral directory (not inside the repo), e.g.
    • opencode web
  3. In the Web UI, open/select the project /home/USER/dev/REPO
  4. Observe the sidebar sessions list: it shows only sessions whose session.directory == /home/USER/dev/REPO (for me: 28 sessions), but does not show the sessions for worktree directories /home/USER/dev/_wt/REPO-*
  5. Compare with TUI/CLI: sessions are present as expected (including the worktree directories)

Screenshot and/or share link

Image

Operating System

Linux

Terminal

No response

Activity

  1. benoitheinrich commented on Feb 18, 2026

    @benoitheinrich
    Author

    Key evidence (API vs Web UI mismatch)

    1) The web server API does return root sessions across multiple directories (repo + worktrees)

    If I query the server in the repo context, GET /session?roots=true returns sessions whose directory spans multiple worktree dirs:

    curl -fsS \
      -H "x-opencode-directory: /home/USER/dev/REPO" \
      "http://127.0.0.1:4096/session?roots=true&limit=1000" \
    | jq -r '[.[].directory] | group_by(.) | map({dir:.[0], count:length}) | sort_by(.count) | .[] | "\(.count)\t\(.dir)"'

    Example output shape (counts vary, but note multiple directories):

    28  /home/USER/dev/REPO
    8   /home/USER/dev/_wt/REPO-WT-1
    2   /home/USER/dev/_wt/REPO-WT-2
    ...
    

    So the backend can see and return root sessions for worktree dirs.

    2) Web UI bundle shows filtering to current directory only (roots + unarchived + directory equality)

    From the downloaded web bundle (minified), two relevant snippets:
    (a) Session list API call is directory-scoped + roots-only (via oX)

    async function oX(t){
      try {
        return {
          data: (await t.list({ directory: t.directory, roots: !0, limit: t.limit })).data,
          limited: !0
        }
      } catch {
        return t.onFallback(), {
          data: (await t.list({ directory: t.directory, roots: !0 })).data,
          limited: !1
        }
      }
    }

    (b) Sidebar list filters sessions to session.directory === currentDirectory (plus root + unarchived)

    const Xle = (s, dir) =>
      normalize(s.directory) === normalize(dir) &&
      !s.parentID &&
      !s.time?.archived;
    zl = (t, now) =>
      t.session
       .filter(s => Xle(s, t.path.directory))
       .sort(sortByRecent(now));

    This matches the observed symptom exactly: the Web UI sidebar shows only root/unarchived sessions whose session.directory equals the currently selected directory, excluding worktree directories.


    What I expected

    When opening the main repo project in Web UI, the sidebar session list should include sessions for:

    • the main repo directory and
    • all worktree/sandbox directories belonging to the same project (or offer a toggle like “This directory” vs “Whole project incl. worktrees/sandboxes”)
      This used to work for me on 1.2.5, and I rely on it to navigate sessions across many worktrees.

    What actually happens

    On 1.2.6, the Web UI sidebar only shows sessions whose session.directory equals the main repo directory (e.g. 28), while TUI/CLI show all sessions and the server API can return root sessions across multiple worktree directories.


    Attempted fixes / ruled out

    Duplicate project rows + merging project IDs in SQLite did not fix it

    My SQLite DB (~/.local/share/opencode/opencode.db) had duplicate project rows for the same worktree path. I wrote and ran a safe script to merge duplicate project IDs and re-associate sessions under one canonical project row (with backups + revert).
    Result:

    • The merge succeeded (sessions moved/merged under one project row)
    • But the Web UI behavior did not change: it still only shows sessions for the current directory and hides worktree directory sessions.

    So this does not appear to be simply “Web UI picking the wrong project id”.


    Regression note (1.2.5 -> 1.2.6)

    This behavior started after upgrading from 1.2.5 to 1.2.6. On 1.2.5, Web UI showed worktree/sandbox sessions for this repo in the sidebar.

    Possibly related changes / commits

    I don’t know the exact offending commit yet, but this seems in the same area as:


    Suggested direction / fix ideas

    If worktrees/sandboxes are a supported concept in Web UI:

    • When the current project has multiple sandboxes/worktrees, the sidebar should include sessions across those directories (or provide a toggle).
    • Alternatively, the sidebar could group sessions by directory and include each sandbox/worktree directory under the same project.
      Happy to provide more sanitized diagnostics if needed (e.g. /project/current output showing sandboxes, additional /session queries, etc.).
  2. Relicus commented on Feb 18, 2026

    @Relicus

    really degraded after "v1.1.65".. I've just reverted back.

  3. benoitheinrich commented on Feb 18, 2026

    @benoitheinrich
    Author

    I tried reverted back to 1.1.65 but still have same problem, I thought that downgrading to 1.2.5 would fix the problem but it didn't.

  4. benoitheinrich commented on Feb 18, 2026

    @benoitheinrich
    Author

    @adamdotdevin I see that you're assigned to this issue, do you want me to give it a try and fix it ?

  5. Relicus commented on Feb 18, 2026

    @Relicus

    Yeah. Same. Opecode isn’t working now. I think have to do a fresh install or something of old version. But I stopped using it. Im using CLI version now and gone back to antigravity

  6. benoitheinrich commented on Feb 19, 2026

    @benoitheinrich
    Author

    I dug deeper into this and can reproduce a related (and I think underlying) failure mode in the current dev backend when using git worktrees/sandboxes. This affects both the Web UI and the TUI depending on which directory you open from.

    What I observed (real reproduction)

    Setup:

    • Backend started from source on a separate port (e.g. serve --port 4097) because my stable install runs on 4096.
    • Project: /home/benoit/dev/sfp-3pl-approval
    • Sandbox/worktree: /home/benoit/dev/_wt/sfp-3pl-approval-SFP-81755

    A root session that clearly belongs to that sandbox exists:

    • title: "Regenerating springSBOM.json and helidonSBOM.json files"
    • id: ses_398fcc074ffeX7XQLbikuQsdNP
    • projectID: 930a00aa130185a96d9860997d5c190eb37da4be
    • directory: /home/benoit/dev/_wt/sfp-3pl-approval-SFP-81755

    You can find it via the API when scoped to the main worktree (header scope):

    • curl -H "x-opencode-directory: /home/benoit/dev/sfp-3pl-approval" --get http://localhost:4097/session --data-urlencode "search=Regenerating springSBOM.json and helidonSBOM.json files" --data-urlencode "limit=50"

    But in the Web UI (workspaces enabled), I see one request per workspace like:

    • GET /session?directory=<workspaceRoot>&roots=true&limit=...

    And here is the key mismatch:

    • GET /project/current?directory=/home/benoit/dev/sfp-3pl-approval returns project id 930a...
    • GET /project/current?directory=/home/benoit/dev/_wt/sfp-3pl-approval-SFP-81755 returns project id 45063dff81483b2c49f6c95b53a7074e2f5c49b5

    So when the UI requests:

    • GET /session?directory=/home/benoit/dev/_wt/sfp-3pl-approval-SFP-81755&roots=true...

    it runs under project 45063... and returns [], even though there is a root session whose directory is exactly that sandbox root — because the session is stored under projectID 930a....

    This is not just hypothetical: GET /project shows two project rows with the same worktree path /home/benoit/dev/sfp-3pl-approval but different ids (930a... and 45063...), and sessions are split across them.

    Also affects the TUI (important)

    This also affects the TUI when you open/attach it from the sandbox directory:

    • If you open/attach the TUI from a sandbox path that resolves to the “other” project ID, you won’t see the “old” sessions that were created under the original project ID.
    • If you create new sessions while in that sandbox, those new sessions show up (because they’re created under the sandbox’s currently-resolved project ID), and they also show up in the Web UI for that workspace. But older sessions remain “missing” in that scope.

    So this is a project identity split across worktrees, not only a UI rendering problem.

    Why this happens (code pointers)

    Project ID resolution for git repos happens in:

    • packages/opencode/src/project/project.ts (Project.fromDirectory())

    Key details:

    • ID is seeded from git rev-list --max-parents=0 --all and it caches the chosen ID in .git/opencode.
    • In git worktrees, .git is per-worktree (and can be a file pointing elsewhere), so the cache can diverge across worktrees.
    • rev-list --all can yield different refs depending on worktree context, so the computed ID can differ.

    Session listing is consistently filtered by the resolved project ID at the DB layer:

    • packages/opencode/src/session/index.ts (Session.list() uses eq(SessionTable.project_id, Instance.project.id) and optionally eq(SessionTable.directory, input.directory))

    So once a repo ends up with two project IDs, sessions created under one ID won't show up when the server resolves the instance to the other ID.

    Proposed fix (minimal + durable)

    There are two parts; doing only one is likely insufficient long-term:

    1. Stabilize project ID resolution across worktrees:
    • Prefer a stable seed (e.g. compute roots from HEAD instead of --all, or otherwise ensure worktree-invariant behavior).
    • Cache the computed ID in the git common dir (e.g. via git rev-parse --git-common-dir) so all worktrees share the same cache, rather than per-worktree .git/opencode.
    1. One-time reconciliation for users already affected:
    • Detect duplicate project rows that share the same worktree but have different id.
    • Migrate sessions from the duplicate project id(s) to the canonical one, merge sandboxes, then remove duplicates.
      (Otherwise existing “old” sessions remain invisible depending on which worktree the instance resolves to.)

    Background / when this likely started (git revs + versions)

    Relevant commits:

    • 0b4af9522 (2026-01-03) "core: add sandbox support for git worktrees..." (introduces sandbox/worktree project id + .git/opencode cache behavior)
    • b02075844 (2026-02-14) "tui: show all project sessions from any working directory" (makes split more visible in TUI behavior)
    • 68bb8ce1d (2026-02-14) "core: filter sessions at database level..." (makes scoping by project_id consistent; per-workspace directory requests now strictly filtered)
    • 6d95f0d14 (2026-02-14) "sqlite again (sqlite again #10597)" (storage changes around this timeframe)

    Release tags containing these:

    • 0b4af9522 is in v1.1.1 (first release tag that contains the sandbox/worktree support commit)
    • b02075844 is in v1.2.1
    • 68bb8ce1d is in v1.2.2 (and thus also in v1.2.6)

    So affected users are most likely those who ended up with duplicated project ids for the same repo across worktrees, typically from earlier runs / differing worktree contexts.

    Happy to provide exact curl commands / additional data if helpful.

  7. benoitheinrich commented on Feb 19, 2026

    @benoitheinrich
    Author

    I've got a working fix and I'll be submitting a PR very soon, I tested locally and my worktrees are back :)

    Image
  8. benoitheinrich commented on Feb 19, 2026

    @benoitheinrich
    Author

    PR for this available here #14287

  9. github-actions commented on Apr 21, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingwebRelates to opencode on web / desktop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions