[BUG] [bug] preview_start permanently broken after project directory rename

Resolved 💬 3 comments Opened May 2, 2026 by flavioponzio Closed May 6, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Summary

mcp__Claude_Preview__preview_start enters an unrecoverable state after the
project directory is renamed/moved while Claude Code is running. The bash
subprocess that the MCP tool spawns (likely inside the VM at
~/Library/Application Support/Claude/vm_bundles/claudevm.bundle/) holds a
stale cwd reference to the old (now-deleted) inode and never recovers.

The MCP server's own cwd is correct — verified in
~/Library/Caches/claude-cli-nodejs/<encoded-path>/mcp-logs-Claude-Preview/*.jsonl,
which logs "cwd":"/Users/.../new-path". The stale state lives somewhere the
spawned bash inherits but I can't reach from the host.

Environment

  • macOS 26.4.1 (arm64)
  • Claude Desktop 1.5354.0
  • Claude Code 2.1.121
  • Node v20.20.2

Reproduction

  1. Open Claude Code on a Next.js project at ~/Desktop/Foo/foo-app/
  2. Configure .claude/launch.json (name: foo-app)
  3. Call preview_start successfully at least once (creates internal state)
  4. Quit Claude Code, rename folder in Finder to ~/Desktop/Bar/bar-app/,

update package.json#name and launch.json#name to bar-app

  1. Reopen Claude Code at the new path and call preview_start

Expected

Preview tool should start the dev server at the new path (read from
launch.json#cwd or the Claude Code process cwd).

Actual

preview_start returns hundreds of repeating lines of:
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Operation not permitted
job-working-directory: error retrieving current directory: getcwd: ...

followed by:
/bin/bash: line 0: cd: foo-app: No such file or directory

The string foo-app is the old folder basename, not present in any
host-readable file (verified with recursive grep across
~/Library/Application Support/Claude/, ~/.claude/, and shell snapshots).

Recovery attempts that did NOT work

  • /exit + claude --continue
  • Full Cmd+Q of Claude.app + reopen
  • Edit .claude/launch.json with absolute cwd and updated name
  • runtimeExecutable: /bin/sh with runtimeArgs: ["-c", "cd '/abs/path' && exec npm run dev"]
  • Recreate old folder + symlink to new path
  • Update like-named alias in ~/.zshrc
  • Patch shell snapshot in ~/.claude/shell-snapshots/snapshot-zsh-*.sh
  • Delete stale session JSONs in

~/Library/Application Support/Claude/claude-code-sessions/<id>/<id>/local_*.json

  • Reset VM sessiondata.img (VM creates fresh — error still persists)
  • Verified Claude Code main process cwd is correct via lsof -p <pid> | grep cwd

Suspected root cause

Stale state persists inside the VM's rootfs.img (the persistent VM
filesystem, which survives sessiondata.img resets), not in any host file.
Some shell history, alias, or saved command inside the VM still references
the old path via relative cd.

Severity / Impact

Blocks preview_start, preview_screenshot, preview_eval, preview_click,
etc. for the rest of the session — and across multiple Claude Code restarts.
The only practical recovery is wiping rootfs.img, which destroys all other
VM state (caches, installed tools, history). Effectively nuclear.

Workaround

Run npm run dev directly via the Bash tool with run_in_background: true,
and validate manually in the host browser instead of through preview_*.
Functional but loses automated browser testing.

Suggested fix

Add a documented command/flag, e.g.:

  • claude doctor --reset-preview — recreates only the preview MCP state
  • claude vm rebuild — wipes claudevm.bundle/ and reprovisions from base

smol-bin.<arch>.img, preserving host configs (settings, sessions, plans)

  • Or, more conservatively: detect on preview_start that getcwd() fails in

the spawned shell and auto-rebuild the bash subprocess fresh from the
current launch.json#cwd instead of inheriting stale state

Either of these would avoid the nuclear option of manually deleting
~/Library/Application Support/Claude/vm_bundles/claudevm.bundle/, which
forces a 7-8 GB redownload and loses all other VM-side caches.

Logs / artifacts

The bug surfaces clearly in the Preview MCP's own log:

~/Library/Caches/claude-cli-nodejs/<encoded-project-path>/mcp-logs-Claude-Preview/<timestamp>.jsonl

Each failed call shows "cwd":"/Users/.../<new-path>" (correct) followed by
the getcwd: Operation not permitted cascade and the final
/bin/bash: line 0: cd: <old-basename>: No such file or directory.

The Claude Code session debug log (~/.claude/debug/<session-id>.txt,
enabled via /debug) only shows tool dispatch level — tool=mcp__Claude_Preview__preview_start ... outcome=error — without the inner
shell stderr, since the failure happens inside the MCP server's own subprocess.

Update — May 2 2026

After preparing this report I "nuked" the VM bundle:## Suggested fix

Add a documented command/flag, e.g.:

  • claude doctor --reset-preview — recreates only the preview MCP state
  • claude vm rebuild — wipes claudevm.bundle/ and reprovisions from base

smol-bin.<arch>.img, preserving host configs (settings, sessions, plans)

  • Or, more conservatively: detect on preview_start that getcwd() fails in

the spawned shell and auto-rebuild the bash subprocess fresh from the
current launch.json#cwd instead of inheriting stale state

Either of these would avoid the nuclear option of manually deleting
~/Library/Application Support/Claude/vm_bundles/claudevm.bundle/, which
forces a 7-8 GB redownload and loses all other VM-side caches.

Logs / artifacts

The bug surfaces clearly in the Preview MCP's own log:

~/Library/Caches/claude-cli-nodejs/<encoded-project-path>/mcp-logs-Claude-Preview/<timestamp>.jsonl

Each failed call shows "cwd":"/Users/.../<new-path>" (correct) followed by
the getcwd: Operation not permitted cascade and the final
/bin/bash: line 0: cd: <old-basename>: No such file or directory.

The Claude Code session debug log (~/.claude/debug/<session-id>.txt,
enabled via /debug) only shows tool dispatch level — tool=mcp__Claude_Preview__preview_start ... outcome=error — without the inner
shell stderr, since the failure happens inside the MCP server's own subprocess.

  • Full VM nuke: backed up ~/Library/Application Support/Claude/vm_bundles/claudevm.bundle/,

reopened Claude.app, new VM provisioned from scratch (new 9.7 GB rootfs.img,
new sessiondata.img, new EFI vars, new MAC, new IP). Bug persists immediately
on preview_start after rebuild.

  • Deleted orphan caches: removed

~/Library/Caches/claude-cli-nodejs/-Users-flavioponzio-Desktop-CRM-Psico/
and ~/.claude/projects/-Users-flavioponzio-Desktop-CRM-Psico/. No effect.

This isolates the stale state to either:
(a) the running Claude Code binary's in-memory state (caches not flushed on
Cmd+Q + relaunch — would imply a daemon/launchd agent or app-level
persistence we couldn't identify), or
(b) server-side state at Anthropic (likely, since this is a remote-mode session
and the Claude Desktop remote-mode keeps session context server-side).

Either way, the bug cannot be resolved by any user-accessible action on macOS.

What Should Happen?

Preview tool should start the dev server at the new path (read from
launch.json#cwd or the Claude Code process cwd).

Error Messages/Logs

preview_start returns hundreds of repeating lines of:
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Operation not permitted
job-working-directory: error retrieving current directory: getcwd: ...

followed by:
/bin/bash: line 0: cd: foo-app: No such file or directory

The string foo-app is the old folder basename, not present in any
host-readable file (verified with recursive grep across
~/Library/Application Support/Claude/, ~/.claude/, and shell snapshots).

Steps to Reproduce

Open Claude Code on a Next.js project at ~/Desktop/Foo/foo-app/
Configure .claude/launch.json (name: foo-app)
Call preview_start successfully at least once (creates internal state)
Quit Claude Code, rename folder in Finder to ~/Desktop/Bar/bar-app/,
update package.json#name and launch.json#name to bar-app
Reopen Claude Code at the new path and call preview_start

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.121

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗