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
tui: cannot remove stale projects from /open list; desktop crashes on non-existent project #49442
Two related issues around handling non-existent project directories:
TUI — /open and /project commands show stale projects that can't be removed:
When a project directory is moved or deleted, the /open and /project commands still list it as a previously opened project. There is no way to remove stale entries. If the user selects one, the session fails or hangs.
Desktop — Settings > Projects shows non-existent projects, and opening them crashes the app:
In the desktop app, the Settings > Projects panel lists previously opened projects. If a project directory has been moved or deleted, it still appears in the list. When the user tries to open it, the app throws:
ClientError: UnexpectedStatus
at i (oc://renderer/assets/health-BdaR9NAA.js:1:41042)
原因:
{
status: 500
}
The desktop app becomes unresponsive and must be manually restarted.
Steps to reproduce
TUI:
Open a project in TUI (/open or startup)
Move or delete that project directory from disk
Run /open or /project again — the old project still appears in the list
There is no option to remove it from the list
Desktop:
Open a project in the desktop app
Move or delete that project directory from disk
Go to Settings > Projects — the old project still appears
Try to open it — the app crashes with ClientError: UnexpectedStatus (status: 500) and must be restarted
Expected Behavior
TUI:/open and /project should detect stale (non-existent) project entries and either remove them automatically or provide a way to delete them from the list
Desktop: Settings > Projects should detect stale entries and either remove them or show a clear error message ("Project directory not found") instead of crashing the app
Actual Behavior
TUI: Stale projects persist in /open and /project lists with no way to clean them up
Desktop: Settings > Projects shows stale entries; opening one crashes the app with a 500 error requiring a full restart
Additional Context
opencode version: 2.0.3
OS: Windows_NT 10.0.26200 (win32 x64)
Terminal: xterm-256color (TUI mode)
Shell: cmd.exe
Install/channel: npm global, latest
Active plugins: None
This is a common scenario when reorganizing project directories or migrating between machines
This issue consolidates all three into one report since they share the same root cause: opencode doesn't validate whether a project directory still exists, and provides no way for users to clean up stale entries from either TUI or desktop. Happy to close this in favor of tracking them separately if that's preferred.
Update: I've been manually removing stale entries from the data files to clean up the project list. This works but is not user-friendly.
Would it be possible to add a command (e.g., /project remove <name> in TUI, or a delete button in Desktop Settings > Projects) that lets users remove project entries directly from the UI? I'd be happy to submit a PR for this if the approach sounds reasonable.
1. TUI command palette — shortcut key for stale project cleanup
In /open and /project panels, add a快捷键 (e.g., d or Delete) to remove a selected project entry. This would work like a quick inline delete without leaving the command palette.
2. CLI subcommand — opencode project
Add a new CLI command with subcommands:
Command
Description
opencode project list
List all registered projects
opencode project del <name>
Remove a project entry from the list
opencode project delsession <name>
Clear all sessions associated with a project
This gives both TUI and CLI users a way to manage projects without manually editing data files.
Happy to submit a PR covering both the TUI shortcut and the CLI subcommands if this approach is acceptable.
DISCLAIMER THIS WAS GENERATED BY OPENCODE/BIG-PICKLE USING THE BUILT IN @report SKILL**
Adding a repro path that isn't in the original description: the trigger here was renaming a project in the desktop project viewer, not moving or deleting the directory. Worth separating because the rename makes the failure fatal, where merely having a stale entry is only survivable.
What I did
Opened a git project in opencode-desktop so it appeared in the project viewer.
Renamed the directory on disk in the file browser (superMemory_Redux_OpenCode → superMemory-Redux_OpenCode). The old entry stayed in the viewer, now pointing at a path that no longer exists.
Opened the stale entry. No crash, but no model could be selected — the model list failed to load.
Opened the renamed directory. Models loaded normally.
Renamed the stale entry in the project viewer to match the new directory name.
opencode-desktop immediately showed an HTTP 500 error screen and never rendered again, on every subsequent launch.
Step 3 is the interesting part: the stale project was already returning 500 before the rename (/api/model failing, surfaced as an unusable model picker). The rename didn't create the fault, it changed which client code path hit it — from a per-request failure you can navigate away from, to a bootstrap failure the renderer treats as unrecoverable.
Evidence
The rename and the first fatal error are 8 seconds apart, with no process restart in between:
11:21:07.496 rename persisted (drafts.sqlite, key workspace:project, value {"name":"superMemory-Redux_OpenCode"})
11:21:15.288 first "fatal renderer error" in the same running session
Every subsequent launch reproduced it identically: 11:21:19, 11:21:39, 11:21:48, 11:22:25, 11:23:58, 11:24:57, 11:25:57, 11:35:08.
lastProject was not repointed. In drafts.sqlite, table state, key server, the lastProject field was last written at 11:20:41 — before the rename — and already pointed at the valid path. So the rename did not make the stale directory the active project. The only value it persisted was a display name, on the stale entry.
After the rename, two entries share the display namesuperMemory-Redux_OpenCode while their worktree paths differ:
That collision is my leading hypothesis for why the rename turns a survivable 500 into a fatal one — something resolves by display name and lands on the stale path. I could not confirm it. I only had the packaged bundle at /usr/lib/opencode-desktop, not the desktop source, so the mechanism inside the rename handler is unverified. The timestamps establish the trigger; the mechanism is inference.
Confirming the lockout, and the workaround
The app crashes before the project viewer can be reached, so there is no in-app way to remove the offending entry — which is the same dead end described in the TUI half of this issue, except here it blocks recovery entirely rather than just cleanup.
With the app closed, removing the stale entry from the server key in drafts.sqlite restores startup. Verified: PRAGMA integrity_check returns ok, and the app launches.
One caveat that cuts against the collision theory: that same project list still contains three other paths that don't exist on disk, and the app launches fine with them present. So bootstrap only appears to fetch config for the active project, not every entry — which doesn't fully explain how the stale entry was reached during bootstrap at all. I'd rather flag that gap than guess at it.
I found an additional related behavior: every time the client resolves locations for these stale/dead projects (where the directory no longer exists), time_active still gets bumped even when location resolution returns 404.
This means these dead projects never age out of the recent project list (Ctrl+O). Instead, they keep jumping back to the top of the list every time the recent projects menu is opened.
This is a separate aggravating factor beyond the projects simply persisting in the database.
Closing this consolidation as a split duplicate. Project removal and TUI/CLI cleanup are tracked in #51197; Desktop missing/inaccessible-folder failures are tracked in #50951. The proposed cleanup commands, fatal-rename reproduction, and time_active details have been transferred to the appropriate issues.
Activity
github-actions commentedon Sep 17, 2026
This issue might be a duplicate of existing issues. Please check:
/openstale-entry problem)XXLxhPLMM commentedon Sep 17, 2026
Thanks for flagging these. I've encountered all three scenarios described in those issues:
/openand/projectwith no way to remove them.This issue consolidates all three into one report since they share the same root cause: opencode doesn't validate whether a project directory still exists, and provides no way for users to clean up stale entries from either TUI or desktop. Happy to close this in favor of tracking them separately if that's preferred.
XXLxhPLMM commentedon Sep 17, 2026
Update: I've been manually removing stale entries from the data files to clean up the project list. This works but is not user-friendly.
Would it be possible to add a command (e.g.,
/project remove <name>in TUI, or a delete button in Desktop Settings > Projects) that lets users remove project entries directly from the UI? I'd be happy to submit a PR for this if the approach sounds reasonable.XXLxhPLMM commentedon Sep 17, 2026
Here's what I had in mind for the implementation:
1. TUI command palette — shortcut key for stale project cleanup
In
/openand/projectpanels, add a快捷键 (e.g.,dorDelete) to remove a selected project entry. This would work like a quick inline delete without leaving the command palette.2. CLI subcommand —
opencode projectAdd a new CLI command with subcommands:
opencode project listopencode project del <name>opencode project delsession <name>This gives both TUI and CLI users a way to manage projects without manually editing data files.
Happy to submit a PR covering both the TUI shortcut and the CLI subcommands if this approach is acceptable.
Drewlius commentedon Oct 5, 2026
DISCLAIMER THIS WAS GENERATED BY OPENCODE/BIG-PICKLE USING THE BUILT IN @report SKILL**
Adding a repro path that isn't in the original description: the trigger here was renaming a project in the desktop project viewer, not moving or deleting the directory. Worth separating because the rename makes the failure fatal, where merely having a stale entry is only survivable.
What I did
superMemory_Redux_OpenCode→superMemory-Redux_OpenCode). The old entry stayed in the viewer, now pointing at a path that no longer exists.Step 3 is the interesting part: the stale project was already returning 500 before the rename (
/api/modelfailing, surfaced as an unusable model picker). The rename didn't create the fault, it changed which client code path hit it — from a per-request failure you can navigate away from, to a bootstrap failure the renderer treats as unrecoverable.Evidence
The rename and the first fatal error are 8 seconds apart, with no process restart in between:
Every subsequent launch reproduced it identically: 11:21:19, 11:21:39, 11:21:48, 11:22:25, 11:23:58, 11:24:57, 11:25:57, 11:35:08.
Renderer log:
Confirmed the 500 comes from the missing directory by querying the running sidecar directly via the
x-opencode-directoryheader:Two details that may matter for the fix
lastProjectwas not repointed. Indrafts.sqlite, tablestate, keyserver, thelastProjectfield was last written at 11:20:41 — before the rename — and already pointed at the valid path. So the rename did not make the stale directory the active project. The only value it persisted was a display name, on the stale entry.After the rename, two entries share the display name
superMemory-Redux_OpenCodewhile theirworktreepaths differ:{ "projects": { "local": [ {"worktree": "/home/user/repos/superMemory-Redux_OpenCode/", "expanded": true}, {"worktree": "/home/user/repos/superMemory_Redux_OpenCode/", "expanded": true} ] }, "lastProject": {"local": "/home/user/repos/superMemory-Redux_OpenCode/"} }That collision is my leading hypothesis for why the rename turns a survivable 500 into a fatal one — something resolves by display name and lands on the stale path. I could not confirm it. I only had the packaged bundle at
/usr/lib/opencode-desktop, not the desktop source, so the mechanism inside the rename handler is unverified. The timestamps establish the trigger; the mechanism is inference.Confirming the lockout, and the workaround
The app crashes before the project viewer can be reached, so there is no in-app way to remove the offending entry — which is the same dead end described in the TUI half of this issue, except here it blocks recovery entirely rather than just cleanup.
With the app closed, removing the stale entry from the
serverkey indrafts.sqliterestores startup. Verified:PRAGMA integrity_checkreturnsok, and the app launches.One caveat that cuts against the collision theory: that same project list still contains three other paths that don't exist on disk, and the app launches fine with them present. So bootstrap only appears to fetch config for the active project, not every entry — which doesn't fully explain how the stale entry was reached during bootstrap at all. I'd rather flag that gap than guess at it.
Environment
/usr/lib/opencode-desktop, sidecar on127.0.0.1:49374~/.config/opencode/plugins/superMemory-Redux_OpenCode.js, plusopencode-wakatimeSuggested additions to the expected behavior
/openfix above.DISCLAIMER THIS WAS GENERATED BY OPENCODE/BIG-PICKLE USING THE BUILT IN @report SKILL**
renengade commentedon Oct 11, 2026
I found an additional related behavior: every time the client resolves locations for these stale/dead projects (where the directory no longer exists),
time_activestill gets bumped even when location resolution returns 404.This means these dead projects never age out of the recent project list (Ctrl+O). Instead, they keep jumping back to the top of the list every time the recent projects menu is opened.
This is a separate aggravating factor beyond the projects simply persisting in the database.
neriousy commentedon Oct 23, 2026
Closing this consolidation as a split duplicate. Project removal and TUI/CLI cleanup are tracked in #51197; Desktop missing/inaccessible-folder failures are tracked in #50951. The proposed cleanup commands, fatal-rename reproduction, and
time_activedetails have been transferred to the appropriate issues.