preview_start pins a stale per-project working directory to a deleted git worktree; ignores config `cwd`

Open 💬 1 comment Opened Jul 8, 2026 by uhhexe

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

  1. In a project, start a session whose working directory is a git worktree under .claude/worktrees/<name>.
  2. Run preview_start once from there (this establishes the per-project preview cwd).
  3. Delete that worktree (git worktree remove .claude/worktrees/<name>).
  4. From any session in that project, run preview_start for any config → fails cd-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_list returns [] → it is not a registered running server.
  • An explicit "cwd" field in the launch config → ignored; it still cds into the stale worktree path.
  • The stale path appears in no on-disk state I could find: not the repo, not git worktree list (only main), 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

  1. 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.
  2. Ignored cwd: an explicit cwd in the launch config does not override the recorded working directory. If cwd is 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."

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗