Skip to content

tui: deleted projects remain selectable in V2 project picker #39903

Closed

Description

@kitlangton

Summary

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.

Environment

  • opencode version: opencode2 v0.0.0-next-16594
  • OS: Darwin 25.5.0, arm64
  • Terminal: Ghostty (TERM=xterm-256color, COLORTERM=truecolor)
  • Shell: /bin/zsh
  • Install/channel: next / V2
  • Active plugins: @kitlangton/opencode-session-recap, local debug workspace plugin, and ~/.config/opencode/plugins/voice.ts

Reproduction

  1. Open a project in the V2 TUI so it is persisted and appears in the project picker.
  2. Delete that project's directory outside OpenCode.
  3. Open the session/project picker with ctrl+o.
  4. Select the deleted project.
  5. 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.

Activity

  1. leizd commented on Aug 2, 2026

    @leizd

    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?

  2. neriousy commented on Oct 21, 2026

    @neriousy
    Member

    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.

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

Metadata

Metadata

Assignees

No one assigned

    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