[Bug]: Initialize Git shows on a thread whose worktree folder was deleted, and fails with git exit 128#29062

opened8d agobyJjohnbarney

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/web, apps/server

Steps to reproduce

  1. Start a thread in a managed worktree (~/.t3/worktrees/<project>/t3-xxxxxxxx) and let a turn finish.
  2. Let storage cleanup remove the worktree folder (storageCleanup.worktreeAfterDays or worktreeOnMerge), or remove it by hand with git worktree remove.
  3. Open the thread and open the thread details panel.
  4. The git section shows Initialize Git instead of the branch controls.
  5. Click Initialize Git.

Expected behavior

The panel says the thread's worktree folder is gone and offers to recreate it from the thread's branch. Turn start already recreates a missing worktree (ProviderTurnStartService, "provider turn start recreating missing worktree"). Initialize Git is not offered, because there is no folder to initialize and the thread's branch still exists in the main repository.

Actual behavior

vcs.init runs git init with the missing folder as its cwd and fails:

1VcsProcessExitError: VCS process failed in GitVcsDriver.initRepository:
2git (~/.t3/worktrees/<project>/t3-73844097) exited with 128 - Process exited with a non-zero status.
3 at VcsProvisioningService.initRepository
4 at ws.rpc.vcs.init

Run by hand, the same command gives fatal: cannot change to '<path>': No such file or directory (exit 128).

Cause (source on main at d890e5c4)

  1. A missing cwd is reported as "not a repository". isMissingGitCwdError (apps/server/src/vcs/GitVcsDriverCore.ts:540) matches the NotFound error for the cwd. The status paths at lines 2098 and 2141 then turn it into null, and line 2209 returns NON_REPOSITORY_STATUS_DETAILS (isRepo: false). That is the same result as a folder that exists and has no .git.
  2. The web client shows Initialize Git whenever isRepo is false (apps/web/src/components/GitActionsControl.tsx:1049 and :1487). gitCwd comes from activeThread.worktreePath (apps/web/src/components/ChatView.tsx:1608-1614), so the button targets the deleted folder.
  3. initRepository (apps/server/src/vcs/GitVcsDriver.ts:779-783) runs git init in input.cwd and does not check that the folder exists.

Suggested fix: give the status a separate "missing" state, or a cwdExists flag. For a managed worktree path that does not exist, show "Worktree removed" with a recreate action in place of Initialize Git, and have vcs.init refuse a cwd that does not exist.

Impact

Minor bug or occasional failure. On my machine it affects 28 of 56 open threads, all of them worktree threads whose folders storage cleanup removed. Every one of them shows Initialize Git, and the button fails each time.

Version or commit

Desktop app 0.1.6 (com.t3tools.t3code), local server.

Environment

macOS 27.2 (Darwin 27.2.0) arm64, git 2.56.0, Claude Code provider. Storage cleanup settings: worktreeAfterDays: 8, worktreeSettledAfterDays: 8, worktreeOnMerge: true.

Workaround

Recreate the worktree at the same path, for example git -C <repo> worktree add <thread worktreePath> <thread branch>. You can also send a message in the thread so turn start recreates it.

  • #27626 (open): Initialize Git on a No project thread runs git init at the scratch root. That is the same button running git init in the wrong place, but for scratch threads. This report covers worktree threads whose folder was deleted.
  • #24797 (open) and #24390 (open): a worktree folder that still exists but no longer holds a checkout. #24797 suggests showing "worktree missing" on the thread, which would also fix this report.
  • #24154 (open): the terminal fails with "cwd does not exist" after cleanup removes the worktree. Same trigger, different control.
  • #21374 (closed as duplicate): sending to a thread whose worktree is gone.