preview_start pins a stale per-project working directory to a deleted git worktree; ignores config `cwd`
Summary
The desktop app's preview subsystem (preview_start / the Claude_Preview MCP) binds a working directory per project and never invalidates it when that directory is a git worktree that gets deleted. Every preview_start for the affected project then fails at a shell cd into the vanished path, for all launch configs, and the binding is not clearable from the project or its .claude/launch.json.
Environment
- Claude desktop app: 1.19367.0
- Bundled claude-code: 2.1.202
- macOS 26.5 (25F71)
What happens
Every preview_start in the affected project fails with:
Failed to start preview server: zsh:cd:1: no such file or directory:
<repoRoot>/.claude/worktrees/<deleted-worktree-name>
Check the command in .claude/launch.json and try again.
The preview subsystem cds into <repoRoot>/.claude/worktrees/<name> before running the launch command. That worktree was the active directory when preview was first started for this project (from a worktree-based session); it was later removed with git worktree remove. The binding survived the deletion.
Why the error message is misleading
It says "Check the command in .claude/launch.json" — but the fault is not in launch.json, and nothing the user can put there fixes it (see below).
Reproduction
- In a project, start a session whose working directory is a git worktree under
.claude/worktrees/<name>. - Run
preview_startonce from there (this establishes the per-project preview cwd). - Delete that worktree (
git worktree remove .claude/worktrees/<name>). - From any session in that project, run
preview_startfor any config → failscd-ing into the deleted worktree path.
What does NOT clear it (all verified)
- A brand-new launch config with a different
name→ same failure (not bound to the config name). - A fresh REPL session → same failure (survives sessions).
preview_listreturns[]→ it is not a registered running server.- An explicit
"cwd"field in the launch config → ignored; it stillcds into the stale worktree path. - The stale path appears in no on-disk state I could find: not the repo, not
git worktree list(onlymain), not.claude/launch.json, not the session JSON (only as a branch name), not~/.claude.json, not~/Library/Application Support/Claude/claude-code/, and not any of the four LevelDB stores (Local Storage, Session Storage, IndexedDB, WebStorage). It appears to be live state in the desktop-app process.
What does clear it
Quitting and reopening the desktop app (re-initializes the preview subsystem with a clean per-project cwd).
Two suspected defects
- Stale-cwd: the preview subsystem persists a per-project working directory pointing at a git worktree and does not invalidate it when the worktree is deleted. It should fall back to the project root (or re-resolve) when the recorded cwd no longer exists.
- Ignored
cwd: an explicitcwdin the launch config does not override the recorded working directory. Ifcwdis intended to be honored, it should win; if it is not a supported field, the error should say so rather than pointing at launch.json.
Suggested fix
Before running a launch config, if the recorded per-project cwd does not exist, fall back to the project root instead of failing — and surface the real reason rather than "check launch.json."
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗