Skip to content

Windows: agent detection fails with WinError 2 for npm-installed CLIs (CreateProcess ignores PATHEXT); 'Configuration Complete' printed but config never written #185

Description

@mKuperElliott

Summary

On Windows, ucode configure --agents claude fails with FileNotFoundError: [WinError 2] when Claude Code is installed via npm, because agent binary detection/validation uses subprocess.run(["claude", ...]) (and ["npm", ...]), which on Windows resolves through CreateProcess — and CreateProcess does not honor PATHEXT. npm installs claude / claude.cmd / claude.ps1 but no claude.exe, so the lookup fails even though claude runs fine from PowerShell or cmd.

Worse, the failure mode is misleading: configure prints "Configuration Complete — Claude Code: configured (Provider: Databricks)" but ~/.claude/ucode-settings.json is never written (the exception fires in install_tool_binary before write_tool_config runs, or in the validator afterwards). The user is left with an agent that appears configured but has no config and no auth.

Environment

  • Windows 10 Enterprise LTSC 2021 (10.0.19045), PowerShell 5.1
  • ucode 0.1.0 (installed via uv tool install git+https://github.com/databricks/ucode, commit a0a0d1c)
  • Python 3.12 (uv-managed)
  • Claude Code 2.1.202 installed via npm install -g @anthropic-ai/claude-code (npm prefix %LOCALAPPDATA%\Programs\nodejs)

Repro

npm install -g @anthropic-ai/claude-code   # produces claude, claude.cmd, claude.ps1 — no .exe
uv tool install git+https://github.com/databricks/ucode
ucode configure --agents claude

Output ends with:

┌───────────────── Configuration Complete ──────────────────┐
│ Claude Code: configured (Provider: Databricks)            │
└───────────────────────────────────────────────────────────┘
┌─────────────── Validating ────────────────┐
ERROR Claude Code: [WinError 2] The system cannot find the file specified

and ~/.claude/ucode-settings.json does not exist.

Minimal reproduction of the underlying cause:

python -c "import subprocess; subprocess.run(['claude','--version'])"
# FileNotFoundError: [WinError 2]  — even though `claude --version` works in the shell

Earlier in the same flow, when claude is absent entirely, the auto-install branch (subprocess.run(["npm", "install", "-g", package]) in agents/__init__.py::install_tool_binary) crashes the same way, because npm is also npm.cmd, not an .exe.

Suggested fix

Resolve binaries with shutil.which() before every subprocess.run on the agent/npm binaries, e.g.:

binary_path = shutil.which(binary)
if binary_path is None:
    ...  # treat as not installed
subprocess.run([binary_path, *args], ...)

shutil.which honors PATHEXT, so claude.cmd / npm.cmd resolve correctly. (Note subprocess.run([...".cmd"...]) also needs the resolved absolute path — passing a bare name with no extension still fails.)

Also worth hardening: if write_tool_config hasn't run, don't print "Configuration Complete" — surface the bootstrap/validation failure as the outcome so users know the config was not written.

Workaround we're using

Compile a tiny claude.exe shim (csc.exe one-liner that re-invokes claude.cmd) into the npm prefix dir so CreateProcess finds a real executable. Works, but shouldn't be necessary.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions