You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Can't delete a workspace whose folder was removed outside OpenCode (DELETE /api/worktree → 400) #57987
OpenCode keeps a workspace (git worktree) after the worktree is removed outside OpenCode. Deleting it in the desktop app fails, so the stale workspace can't be removed from the UI.
Environment
OpenCode Desktop 2.1.2 (arm64), macOS 27.0.1
Steps to reproduce (what happened in my case)
Create a git worktree outside OpenCode, e.g. git -C <repo> worktree add ../.worktrees/<name> -b <name>.
Work in it with OpenCode. The service registers it on its own: it runs git worktree list --porcelain from that folder and saves it as a workspace of the repo's project (worktree table, strategy = git).
Remove the worktree outside OpenCode. The folder is gone and git worktree list no longer shows it.
In the desktop app, delete the workspace.
Expected
Deleting a workspace whose folder no longer exists removes the saved record. Better: the app drops it automatically once git no longer lists it.
Actual
The app shows an error and the workspace stays. Service log, three attempts:
GET /api/worktree?projectID=<id> keeps returning the deleted directory.
Workaround
Re-syncing the project with git removes it:
opencode api worktree.refresh -d '{"projectID":"<project id>"}'
Suggested fix
In worktree.remove: if the directory is missing or git no longer lists the worktree, drop the saved record instead of returning 400 (or offer "Remove from list").
Or run the worktree.refresh reconciliation when the app lists workspaces.
Thanks for the detailed report. I reproduced this on 2.1.2 through the server API, and it still happens on the latest dev (248bfbe).
Steps:
Create a git worktree outside OpenCode with git worktree add ../wt -b wt, and use it as a location so it's saved as a git worktree of the project.
Remove it with git worktree remove ../wt.
DELETE /api/worktree for that directory returns 400 Worktree directory unavailable: <dir>, with force: false and with force: true.
GET /api/worktree keeps listing the directory until POST /api/worktree/refresh runs, which matches your workaround.
The script below runs all of this against an isolated opencode serve.
It looks like the remove path checks that the folder exists before it looks up and deletes the saved record, so a folder deleted outside OpenCode can't be removed this way.
Related: #54827 (reload fails after a managed worktree folder is removed outside OpenCode) and #51172 (on Windows, a partial removal leaves a stale record).
The three directories still show up in the desktop workspaces panel, each with "0 sessions".
They are projects, not worktrees: GET /api/project returns them with canonical = the deleted directory, no vcs field, and GET /api/worktree?projectID=<id> returns [] for each.
What I tried against the running server
POST /api/worktree/refresh {projectID: <main repo>} → 204, no effect.
POST /api/worktree/refresh {projectID: <stale>} → 400 Worktree directory unavailable: D:\...\wt\admin.
DELETE /api/worktree {projectID, directory, force: true} → 400 Invalid worktree directory: D:\...\wt\admin, even after recreating the directory and registering it as a real git worktree again.
PATCH /api/project/{id} {"archived": true} → 200, but the field is dropped (additionalProperties: false; only canonical, name, icon, commands are accepted) and the row is still returned by GET /api/project?archived=false.
DELETE /api/project/{id} → 404, no such route.
Clearing the desktop client state (Local Storage, IndexedDB, drafts.sqlite) → no effect, so the records live server-side.
Expected: a project whose canonical directory no longer exists should be dropped automatically (same reconciliation worktree.refresh is supposed to do for worktrees), or at least be removable. Accepting archived in project.update would also be enough to hide it.
Is there a supported way to remove such a project in 2.2.1?
Activity
opencode-agent commentedon Oct 22, 2026
Thanks for the detailed report. I reproduced this on 2.1.2 through the server API, and it still happens on the latest
dev(248bfbe).Steps:
git worktree add ../wt -b wt, and use it as a location so it's saved as agitworktree of the project.git worktree remove ../wt.DELETE /api/worktreefor that directory returns 400Worktree directory unavailable: <dir>, withforce: falseand withforce: true.GET /api/worktreekeeps listing the directory untilPOST /api/worktree/refreshruns, which matches your workaround.The script below runs all of this against an isolated
opencode serve.It looks like the remove path checks that the folder exists before it looks up and deletes the saved record, so a folder deleted outside OpenCode can't be removed this way.
Related: #54827 (reload fails after a managed worktree folder is removed outside OpenCode) and #51172 (on Windows, a partial removal leaves a stale record).
Reproduction script (repro.sh)
Run it:
bash repro.shwthsama commentedon Oct 29, 2026
Same class of problem as reported here, but for project records rather than worktree rows.
Environment: OpenCode Desktop 2.2.1, Windows 11, bundled
opencode-cli2.2.1-x64 (server runs asopencode-cli.exe serve --service).What happened
git worktree add ../wt/<name> main) and ran sessions in them.git worktree remove --force ...+git worktree prune).They are projects, not worktrees:
GET /api/projectreturns them withcanonical= the deleted directory, novcsfield, andGET /api/worktree?projectID=<id>returns[]for each.What I tried against the running server
POST /api/worktree/refresh {projectID: <main repo>}→ 204, no effect.POST /api/worktree/refresh {projectID: <stale>}→ 400Worktree directory unavailable: D:\...\wt\admin.DELETE /api/worktree {projectID, directory, force: true}→ 400Invalid worktree directory: D:\...\wt\admin, even after recreating the directory and registering it as a realgit worktreeagain.PATCH /api/project/{id} {"archived": true}→ 200, but the field is dropped (additionalProperties: false; onlycanonical,name,icon,commandsare accepted) and the row is still returned byGET /api/project?archived=false.DELETE /api/project/{id}→ 404, no such route.Local Storage,IndexedDB,drafts.sqlite) → no effect, so the records live server-side.Expected: a project whose
canonicaldirectory no longer exists should be dropped automatically (same reconciliationworktree.refreshis supposed to do for worktrees), or at least be removable. Acceptingarchivedinproject.updatewould also be enough to hide it.Is there a supported way to remove such a project in 2.2.1?