preview_start always fails with 'No such file or directory' regardless of launch.json config
Bug Report: Claude Code preview_start MCP tool always fails with "No such file or directory"
Summary
The mcp__Claude_Preview__preview_start tool in Claude Code fails with Failed to spawn process: No such file or directory regardless of what's in .claude/launch.json, including configurations that use standard system binaries that definitely exist.
Environment
- macOS 25.3.0 (Darwin)
- Claude Code (powered by claude-opus-4-6[1m])
- Homebrew at
/opt/homebrew/bin - Node v25.8.1 installed at
/opt/homebrew/Cellar/node/25.8.1_1/bin/node
Reproduction
Create a minimal .claude/launch.json that uses a binary that definitely exists:
{
"version": "0.0.1",
"configurations": [
{
"name": "dev",
"runtimeExecutable": "/bin/ls",
"runtimeArgs": ["/tmp"],
"port": 8080,
"autoPort": false
}
]
}
Then call preview_start with name: "dev".
Expected: Either server starts or a meaningful error (e.g. "this isn't a server")
Actual: Failed to start preview server: Failed to spawn process: No such file or directory
/bin/ls and /tmp both definitely exist:
$ ls -la /bin/ls /tmp
-rwxr-xr-x 1 root wheel 154624 Feb 25 04:41 /bin/ls
lrwxr-xr-x@ 1 root wheel 11 Feb 25 04:41 /tmp -> private/tmp
Other configurations tried (all fail with the same error)
npm/["run", "dev"](npm is at/opt/homebrew/bin/npm)/opt/homebrew/bin/npm(absolute path)/opt/homebrew/Cellar/node/25.8.1_1/bin/node/["./node_modules/vite/bin/vite.js"]/opt/homebrew/Cellar/node/25.8.1_1/bin/node/["/absolute/path/to/vite.js"]/bin/bash/["-c", "...full command..."]/usr/bin/env/["node", "vite.js"]/bin/bash/["./wrapper.sh"](shell wrapper with#!/bin/bashshebang)
Every single one fails immediately with "Failed to spawn process: No such file or directory".
Workaround
Running the exact same command via the Bash tool in the background works perfectly:
/opt/homebrew/Cellar/node/25.8.1_1/bin/node ./node_modules/vite/bin/vite.js
→ Server starts on port 8080, app serves fine.
Impact
preview_startis completely unusable in this environment.- Claude has to use
Bash+run_in_background: trueas a workaround. - Worse: the
Stophook in the harness expects the preview server to be managed bypreview_startand complains every time code is edited, even when a manually-started dev server is running.
Hypothesis
It looks like preview_start either (a) has a hard-coded PATH that doesn't include /opt/homebrew/bin, or (b) passes the runtimeExecutable/runtimeArgs to a spawn call with a malformed cwd or environment, and the ENOENT is coming from a chdir() step rather than the exec() step. The error message misleadingly says "Failed to spawn" no matter what the actual underlying error was.
Suggested Fix
- Make the error message distinguish between "binary not found", "cwd doesn't exist", and "interpreter for shebang not found".
- Accept a
cwdfield inlaunch.json(or at least default to the project root where.claude/launch.jsonlives). - When spawning via shell, inherit the user's login PATH rather than a minimal PATH that's missing
/opt/homebrew/binand similar.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗