Skip to content

[Bug]: openclaw plugins install fails on Windows when Node.js path contains spaces (e.g. C:\Program Files\nodejs) #37563

@ChrisJaunes

Description

@ChrisJaunes

Bug type

Behavior bug (incorrect output/state without crash)

Summary

openclaw plugins install fails on Windows when Node.js is installed in a path containing spaces (e.g. C:\Program Files\nodejs). The npm pack step produces garbled output and exits non-zero because the resolved npm-cli.js path is not properly handled in the spawn call.

Steps to reproduce

  1. Install Node.js on Windows using the official installer (default path: C:\Program Files\nodejs).
  2. Install openclaw globally: npm install -g openclaw
  3. Run: openclaw plugins install

Expected behavior

The plugin downloads, extracts, and installs successfully.

Actual behavior

npm pack fails with garbled output. The path C:\Program Files... is split at the space, producing an error like:

  Downloading <package>...
  (node: 1552) [DEP0190] DeprecationWarning: Passing args to a child process with shell option true can lead to security vulnerabilities, as the arguments are 
  not escaped, only concatenated.
  (Use 'node --trace-deprecation...' to show where the warning was created)
  npm pack failed: ': \Progran' <garbled binary output>

OpenClaw version

2026.3.3

Operating system

windows 11

Install method

npm global

Logs, screenshots, and evidence

Logs: 

$ openclaw plugins install xx
  Downloading xx...
  (node: 1552) [DEP0190] DeprecationWarning: Passing args to a child process with shell option
   true can lead to security vulnerabilities, as the arguments are not escaped, only concatenated.
  (Use 'node --trace-deprecation...' to show where the warning was created)
  npm pack failed: ': \Progran' +<garbled binary output>

evidence:
Root cause analysis:
  The issue is in src/process/exec.ts — the runCommandWithTimeout function, called from src/infra/install-source-utils.ts:218 during npm pack.
  The call chain is:

  installPluginFromNpmSpec (src/plugins/install.ts:497)
    → installFromNpmSpecArchive (src/infra/npm-pack-install.ts:96)
      → packNpmSpecToArchive (src/infra/install-source-utils.ts:218)
        → runCommandWithTimeout(["npm", "pack", spec, ...], { cwd: tmpDir })
          → src/process/exec.ts:225-242

  In runCommandWithTimeout (line 225-242), resolveNpmArgvForWindows resolves ["npm", "pack", ...] to:
  ["C:\Program Files\nodejs\node.exe",
   "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js",
   "pack", spec, "--ignore-scripts", "--json"]
  These are passed to spawn():
  spawn(
    "C:\\Program Files\\nodejs\\node.exe",
    ["C:\\Program Files\\nodejs\\...\\npm-cli.js", "pack", spec, ...],
    { cwd, windowsVerbatimArguments: undefined /* NOT set */ }
  );
  When windowsVerbatimArguments is not set, Node.js applies its own argument escaping for CreateProcessW. On certain Node versions, this escaping can mishandle
   Windows paths that contain both backslashes and spaces, causing the command line to be garbled.
  There is also a secondary issue: if resolveNpmArgvForWindows returns null (e.g. Node installed via nvm-windows / volta / fnm where npm-cli.js is not at the  
  expected location), resolveCommand("npm") returns bare "npm" (since "npm" was removed from the cmdCommands list in commit a1a8ec687), so spawn("npm", ...) is
   called without shell or cmd wrapper, which causes EINVAL on Node 18.20.2+.

Impact and severity

Affected: All Windows users with Node.js installed in a path containing spaces (the default
C:\Program Files\nodejs\ path from the official Node.js installer)
Severity: High (completely blocks plugin installation)
Frequency: 100% reproducible when Node.js path contains spaces
Consequence: Users cannot install any plugin via npm spec on Windows

Additional information

Suggested fix: In src/process/exec.ts, when resolveNpmArgvForWindows produces argv entries containing spaces, the spawn call at line 228 should either:

  1. Route through the cmd.exe wrapper path (using buildCmdExeCommandLine + windowsVerbatimArguments: true), which already correctly handles space-containing
    arguments via escapeForCmdExe, or
  2. Explicitly set windowsVerbatimArguments: true and manually quote argv entries that contain spaces before passing them to spawn.

For the secondary issue (when resolveNpmArgvForWindows returns null), resolveCommand should add "npm" and "npx" back to the .cmd resolution list, or
runCommandWithTimeout should detect the fallback and route through the cmd.exe wrapper.

Related prior fix: a1a8ec6 (fix(windows): land #31147 plugin install spawn EINVAL).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingbug:behaviorIncorrect behavior without a crash

    Type

    No type
    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