Repository navigation
Description
Summary
In the TUI, the worktree affordance is offered for a project whose directory is not a version-controlled repository. Creating one fails with HTTP 400 and Worktree directory unavailable: <dir>. The action can never succeed, and the affordance stays reachable without any keybind.
Environment
- opencode version: 2.0.28
- OS: Windows (platform-independent; the defect is in worktree strategy resolution, not in the OS)
- Terminal: omitted (not relevant to the defect)
- Shell: omitted (not relevant to the defect)
- Install/channel: release
- Active plugins: none required to reproduce; the default git strategy is sufficient
Reproduction
- Open (or move a session into) a project directory that is not a git (or hg) repository.
- Open the worktree / move-session dialog for that project.
- Create a new worktree.
- Observe
POST /api/worktreereturningHTTP 400with messageWorktree directory unavailable: <dir>.
Expected Behavior
For a project with no VCS, the worktree affordance should be hidden, or explained as unavailable, rather than presented as a working action.
Actual Behavior
The dialog offers "new worktree"; the create call returns HTTP 400 Worktree directory unavailable: <dir>.
Additional Context
Root cause (from public source)
The worktree strategy is git-only. Repository discovery finds nothing for a non-repo directory, so create raises DirectoryUnavailableError, and the server maps it to a 400:
packages/core/src/worktree/git.ts:18(create) and:29(list) -if (!repository) return yield* new DirectoryUnavailableError(...)aftergit.repo.discover(...).packages/core/src/worktree/directory.ts:14-canonicalraisesDirectoryUnavailableErrorwhen the path is not a directory.packages/server/src/handlers/worktree.ts:59-Worktree.DirectoryUnavailableErrorbecomesWorktree directory unavailable: <dir>, surfaced throughbadRequestforworktree.create(handler registered atpackages/server/src/handlers/worktree.ts:17).
Why disabling keybinds is not a workaround
The dialog remains reachable without keyboard shortcuts:
- Inline literal bindings in the dialog's own
bindingsarray, bypassing the keymap:packages/tui/src/component/dialog-open.tsx:384,410,415(e.g.ctrl+n-> New worktree). - Palette and slash entries:
session.move(slash: worktrees) atpackages/tui/src/component/prompt/index.tsx:618-627;open.menu(slash: open) atpackages/tui/src/app.tsx:763-772. - Mouse footer actions rendered through the select dialog footer:
packages/tui/src/ui/dialog-select.tsx:626(FooterAction), used by the workspaces dialog. - Automatic worktree list plus refresh fired when the dialog opens:
packages/tui/src/component/dialog-open.tsx:121-134andpackages/tui/src/component/dialog-workspaces.tsx:96-107.
The four dialog.move_session.* keybinds (new, move, delete, refresh - packages/tui/src/config/keybind.ts:268-271) can be disabled, but the affordance itself cannot be removed by configuration.
Activity
opencode-agent commentedon Oct 13, 2026
Thanks for the detailed report. I reproduced this on 2.0.28, and it still happens on the latest
dev(e9def88).Steps, in a plain folder with no
.gitor.hg:/worktrees. The Worktrees dialog shows "No worktrees available" but still offersnew ctrl+a.ctrl+aand enter a name. The prompt footer then shows (new worktree).One difference: on this path the error was
Worktree source not found: <dir>, notWorktree directory unavailable: <dir>. I think your project directory was already registered (for example after a session move), so the request got as far as the git strategy and failed there instead. The underlying problem is the same: worktree creation is offered for a project with no VCS and can never succeed.The recording and screenshots below show this, and the script below reproduces it. Related reports:
.git/.hgrecording.mp4
Reproduction script (drive.ts)
Run it with opencode-drive:
opencode-drive run ./drive.ts. It drivesopencodefrom yourPATH; setOC_DEVto the path of an OpenCode checkout to run that from source instead.drakeo338 commentedon Oct 13, 2026
I'm looking at this and plan to open a fix shortly.
drakeo338 commentedon Oct 21, 2026
Releasing this one: I won't be opening the PR after all, so anyone is welcome to pick it up.