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

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions