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: deleted projects remain selectable in V2 project picker #39903
The V2 TUI project picker can offer a persisted project whose canonical directory has since been deleted. Selecting it leaves the home prompt targeting the deleted path while the footer can still show the previous resolved project, and prompt submission then fails.
Active plugins: @kitlangton/opencode-session-recap, local debug workspace plugin, and ~/.config/opencode/plugins/voice.ts
Reproduction
Open a project in the V2 TUI so it is persisted and appears in the project picker.
Delete that project's directory outside OpenCode.
Open the session/project picker with ctrl+o.
Select the deleted project.
Enter and submit a prompt.
Expected Behavior
A deleted or otherwise unavailable project should not put the TUI into an invalid location state. The picker should either prevent selection or handle the unavailable project explicitly while preserving the current valid location.
Actual Behavior
The deleted project remains selectable. After selection, the path shown under the prompt points at the deleted project while the bottom-left footer can continue to show the previous project. Submitting a prompt fails because the selected directory no longer exists.
Additional Context
Project.list() currently represents persisted known projects and does not account for filesystem changes after persistence. The project picker turns those records directly into selectable directory targets.
The desired project lifecycle semantics need design before implementation. Options include:
Filter unavailable directories when listing projects, at the cost of one filesystem lookup per persisted project and changing Project.list() from “known” to “currently reachable.”
Validate only the selected directory before changing route/location state, then show an error and optionally evict the stale local picker entry.
Add an explicit stale/deleted project lifecycle or cleanup mechanism.
PR #39899 contains a list-time filtering prototype, but it is being closed so these semantics can be decided first.
To keep the first PR focused, I propose validating the selected project's directory before changing the current TUI location. If the directory no longer exists, the picker would show an error, keep the current valid project selected, and avoid entering an invalid location state.
This approach would preserve the current meaning of Project.list() as a list of known projects, rather than adding filesystem checks for every project during listing. I would also add regression coverage for selecting a deleted project and verifying that the current location remains unchanged.
Does this direction match the intended project lifecycle semantics? If so, could you assign this issue to me?
Partly done: #54354 added an archive sweep that runs at startup and then every hour. Projects whose directory no longer exists are archived and hidden from GET /api/project and the picker. A project deleted since the last sweep can still be picked, because nothing checks the directory at selection time. Closing this tracker. That remaining gap can be its own issue.
Activity
leizd commentedon Aug 2, 2026
Hi, I'd like to work on this issue.
To keep the first PR focused, I propose validating the selected project's directory before changing the current TUI location. If the directory no longer exists, the picker would show an error, keep the current valid project selected, and avoid entering an invalid location state.
This approach would preserve the current meaning of
Project.list()as a list of known projects, rather than adding filesystem checks for every project during listing. I would also add regression coverage for selecting a deleted project and verifying that the current location remains unchanged.Does this direction match the intended project lifecycle semantics? If so, could you assign this issue to me?
neriousy commentedon Oct 21, 2026
Partly done: #54354 added an archive sweep that runs at startup and then every hour. Projects whose directory no longer exists are archived and hidden from
GET /api/projectand the picker. A project deleted since the last sweep can still be picked, because nothing checks the directory at selection time. Closing this tracker. That remaining gap can be its own issue.