Skip to content

fix(windows): Claude Code fails to launch with ENOENT (uv_spawn) - #9

Open
Satelius wants to merge 1 commit into
Lordymine:masterfrom
Satelius:fix/windows-claude-spawn-enoent
Open

fix(windows): Claude Code fails to launch with ENOENT (uv_spawn)#9
Satelius wants to merge 1 commit into
Lordymine:masterfrom
Satelius:fix/windows-claude-spawn-enoent

Conversation

@Satelius

@Satelius Satelius commented Jun 25, 2026

Copy link
Copy Markdown

Problem

On Windows, opencode-go fails to launch Claude Code:

■ Failed to start Claude Code: ENOENT: no such file or directory, uv_spawn 'C:\Users...\AppData\Roaming\npm\claude'

Even though claude is installed and on PATH.

Root cause

resolveClaudePath() runs where claude and takes the first line. On Windows, npm installs three shims side by side:

C:...\npm\claude ← extension-less sh shim (listed FIRST)
C:...\npm\claude.cmd ← Windows batch launcher
C:...\npm\claude.ps1

child_process.spawn without shell: true uses CreateProcess, which cannot execute the extension-less sh shim. So spawn fails with ENOENT — not "file not found", but "no way to execute it".

Fix

  1. src/path.tsresolveClaudePath() now prefers the .cmd / .exe / .bat candidate from where instead of blindly taking line 0.
  2. src/cli.tsrunClaudeCode() spawns with shell: true on win32, since .cmd batch files must run through cmd.exe.

Both changes are scoped to process.platform === "win32"; macOS/Linux behavior is untouched.

Verification

  • tsc --noEmit passes
  • where claude now resolves to ...\claude.cmd
  • claude.cmd --version2.1.191 (Claude Code)
  • Launch flow that previously ENOENT'd now starts Claude Code correctly

Summary by CodeRabbit

  • Bug Fixes
    • Improved Windows launching so the app can start the Claude Code launcher reliably when it’s provided as a batch-style executable.
    • Enhanced launcher detection on Windows to better handle multiple installed paths and prefer a valid executable format.

On Windows, `where claude` lists the extension-less npm sh shim first.
child_process.spawn without a shell uses CreateProcess, which cannot
execute that shim, so launching Claude Code fails with
`ENOENT: no such file or directory, uv_spawn '...\npm\claude'`.

- resolveClaudePath: prefer the .cmd/.exe/.bat candidate from `where`
- runClaudeCode: spawn with shell:true on win32 so cmd.exe runs the
  resolved .cmd launcher

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 04ce2827-0d0d-42f0-b5f4-dd6160835fec

📥 Commits

Reviewing files that changed from the base of the PR and between af47bcb and d6751a1.

📒 Files selected for processing (2)
  • src/cli.ts
  • src/path.ts

📝 Walkthrough

Walkthrough

The PR updates Windows launching for Claude Code by broadening path resolution across where claude results and starting the process with a Windows shell so .cmd launchers can run.

Changes

Windows Claude launch handling

Layer / File(s) Summary
Windows launcher resolution
src/path.ts
resolveClaudePath now inspects all where claude output lines on Windows and returns the first .cmd, .exe, or .bat candidate, otherwise the first candidate or claude.
Windows spawn options
src/cli.ts
runClaudeCode() now passes shell: process.platform === "win32" in the spawn(...) options alongside the existing stdio and env values.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A bunny hopped on Windows bright,
Sniffed out the launcher path just right.
With shell set true, off Claude did go,
A happy hop through cmd.exe’s glow.
(_/)\
( •_•)
/ >🍃

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the Windows launch fix and the ENOENT issue addressed by the changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant