Summary
On Windows, launching a managed agent fails immediately: the harness can't find node, every agent errors with '"node"' is not recognized, and buzz-acp exits non-zero. The cause is that the managed-agent runtime launch overrides the child PATH with an augmented value that omits the real Windows process PATH, so system-installed Node (C:\Program Files\nodejs\) disappears.
This is a sibling of the PATH work in #2247 (install-shell) and #2299 (discovery, Linux/macOS), but at a third site: the runtime launch path (managed_agents/runtime.rs + runtime/path.rs), on Windows.
Environment
- OS: Windows 11 (10.0.26200)
- Runtime: Claude Code —
claude CLI v2.1.217, adapter @agentclientprotocol/claude-agent-acp v0.60.0 (installed to the system npm prefix %APPDATA%\npm)
- Node: system install at
C:\Program Files\nodejs\node.exe, on the persistent (Machine) PATH. Not Buzz-managed, not nvm.
- Git for Windows / Git Bash: installed
Steps to reproduce
- Windows 11, Node installed via the official installer only (on the system
PATH; no nvm, no Buzz-managed Node runtime present).
- Install the Claude Code ACP adapter to the system npm prefix:
npm install -g @agentclientprotocol/claude-agent-acp.
- Create/launch a managed agent using the Claude Code runtime.
Actual behavior
The harness exits with status code 1; every agent fails to initialize:
INFO buzz_acp: buzz-acp starting: relay=wss://<redacted> pubkey=<redacted> agent_cmd=C:\Users\<user>\AppData\Roaming\npm\claude-agent-acp.cmd ... model=haiku permission_mode=bypassPermissions respond_to=anyone
'"node"' is not recognized as an internal or external command,
operable program or batch file.
ERROR buzz_acp: agent initialize failed: Agent process exited unexpectedly agent=0
... (repeats for every agent)
Error: all 12 agents failed to start — cannot continue
The claude-agent-acp.cmd shim falls back to bare node (relying on PATH) when there is no node.exe beside it, and the child's PATH has no Node dir.
Root cause
desktop/src-tauri/src/managed_agents/runtime.rs builds an augmented PATH and unconditionally overrides the child's PATH with it:
let augmented_path = build_augmented_path(
dirs::home_dir(),
std::env::current_exe().ok().and_then(|exe| exe.parent().map(Path::to_path_buf)),
login_shell_path(), // None on Windows (by design, see below)
nvm_bin, // ~/.nvm — Unix nvm; None on Windows
);
// ...
if let Some(ref path) = augmented_path {
command.env("PATH", path); // <-- overrides the child PATH
}
build_augmented_path (runtime/path.rs) assembles: ~/.local/bin, Buzz-managed npm/node bin dirs (if present), nvm_bin, exe parent, and the login-shell PATH. It never includes the process PATH.
On Windows:
login_shell_path() returns None on purpose — its own comment says "Return None so they inherit the real Windows PATH instead" (Git Bash returns POSIX colon paths that poison native children).
nvm_bin is None (Unix ~/.nvm layout).
- Buzz-managed npm/node dirs are
None when the user relies on system Node.
But ~/.local/bin and the exe parent are still pushed, so build_augmented_path returns Some(...) — a value with no Node dir and no process PATH. runtime.rs then sets that as the child PATH, defeating the exact inheritance that login_shell_path() == None was meant to preserve. System Node vanishes.
Consequently, adding Node to the system PATH does not help — the runtime replaces PATH rather than extending it.
Proposed fix
Mirror the install-shell fix from #2247: on Windows, base the child PATH on the process PATH and prepend the managed dirs, rather than emitting a managed-only PATH. Concretely, have build_augmented_path (or its runtime.rs caller) include std::env::var("PATH") as the trailing base on Windows when login_shell_path() is None, so managed bins are prepended and the real Windows PATH (with system Node) is retained.
This also aligns the runtime launch with the stated intent of the login_shell_path() Windows branch.
Workaround
Drop a copy of node.exe beside the shims so the .cmd resolves Node without PATH (the shim checks IF EXIST "%dp0%\node.exe" first). This fixes every npm shim in that dir:
copy "C:\Program Files\nodejs\node.exe" "%APPDATA%\npm\node.exe"
Happy to open a PR for the proposed fix if it's welcome.
Summary
On Windows, launching a managed agent fails immediately: the harness can't find
node, every agent errors with'"node"' is not recognized, andbuzz-acpexits non-zero. The cause is that the managed-agent runtime launch overrides the childPATHwith an augmented value that omits the real Windows processPATH, so system-installed Node (C:\Program Files\nodejs\) disappears.This is a sibling of the PATH work in #2247 (install-shell) and #2299 (discovery, Linux/macOS), but at a third site: the runtime launch path (
managed_agents/runtime.rs+runtime/path.rs), on Windows.Environment
claudeCLI v2.1.217, adapter@agentclientprotocol/claude-agent-acpv0.60.0 (installed to the system npm prefix%APPDATA%\npm)C:\Program Files\nodejs\node.exe, on the persistent (Machine)PATH. Not Buzz-managed, not nvm.Steps to reproduce
PATH; no nvm, no Buzz-managed Node runtime present).npm install -g @agentclientprotocol/claude-agent-acp.Actual behavior
The harness exits with status code 1; every agent fails to initialize:
The
claude-agent-acp.cmdshim falls back to barenode(relying onPATH) when there is nonode.exebeside it, and the child'sPATHhas no Node dir.Root cause
desktop/src-tauri/src/managed_agents/runtime.rsbuilds an augmentedPATHand unconditionally overrides the child'sPATHwith it:build_augmented_path(runtime/path.rs) assembles:~/.local/bin, Buzz-managed npm/node bin dirs (if present),nvm_bin, exe parent, and the login-shellPATH. It never includes the processPATH.On Windows:
login_shell_path()returnsNoneon purpose — its own comment says "Return None so they inherit the real Windows PATH instead" (Git Bash returns POSIX colon paths that poison native children).nvm_binisNone(Unix~/.nvmlayout).Nonewhen the user relies on system Node.But
~/.local/binand the exe parent are still pushed, sobuild_augmented_pathreturnsSome(...)— a value with no Node dir and no processPATH.runtime.rsthen sets that as the childPATH, defeating the exact inheritance thatlogin_shell_path() == Nonewas meant to preserve. System Node vanishes.Consequently, adding Node to the system
PATHdoes not help — the runtime replacesPATHrather than extending it.Proposed fix
Mirror the install-shell fix from #2247: on Windows, base the child
PATHon the processPATHand prepend the managed dirs, rather than emitting a managed-onlyPATH. Concretely, havebuild_augmented_path(or itsruntime.rscaller) includestd::env::var("PATH")as the trailing base on Windows whenlogin_shell_path()isNone, so managed bins are prepended and the real WindowsPATH(with system Node) is retained.This also aligns the runtime launch with the stated intent of the
login_shell_path()Windows branch.Workaround
Drop a copy of
node.exebeside the shims so the.cmdresolves Node withoutPATH(the shim checksIF EXIST "%dp0%\node.exe"first). This fixes every npm shim in that dir:Happy to open a PR for the proposed fix if it's welcome.