Skip to content

fix: use process.execPath for .js module spawning on all platforms @W-21984392@ - #1383

Open
WillieRuemmele wants to merge 2 commits into
mainfrom
wr/fixSpawnEnoentOnUnixTarballs
Open

fix: use process.execPath for .js module spawning on all platforms @W-21984392@#1383
WillieRuemmele wants to merge 2 commits into
mainfrom
wr/fixSpawnEnoentOnUnixTarballs

Conversation

@WillieRuemmele

@WillieRuemmele WillieRuemmele commented Aug 6, 2026

Copy link
Copy Markdown

Summary

  • Remove the win32 platform guard in spawn.ts so .js module paths are invoked via Node on all platforms, not just Windows
  • Use process.execPath instead of the string 'node' — ensures the bundled Node binary is used in standalone tarball deployments
  • Add unit tests covering .js path handling (Unix + args passthrough + paths with spaces) and non-.js path passthrough

Fixes #1293

Work Item

@W-21984392@: [oclif][ISSUE] spawn fails with ENOENT on standalone tarballs (UNIX)

Bug Reproduction

The bug occurs when a .js file (e.g., npm-cli.js) has a shebang pointing to a Node interpreter that doesn't exist on the host (common in standalone tarball deployments where only the bundled node exists):

=== OLD behavior: spawn .js directly ===
Spawning: /tmp/repro/npm-cli.js

ERROR: ENOENT — spawn /tmp/repro/npm-cli.js ENOENT
^ The OS tries the shebang interpreter (#!/usr/bin/nonexistent-node)
  which does not exist → ENOENT

=== NEW behavior: spawn via process.execPath ===
Spawning: /path/to/node /tmp/repro/npm-cli.js

Exit code: 0
Output: npm install success

✓ Fix works — process.execPath bypasses the broken shebang

On Unix, ENOENT from spawn() can mean "missing shebang interpreter," not just "target file missing" — which makes this error confusing to diagnose.

Proof of Work

  • Tests: 32 passing (0 failing)
  • Lint: clean
  • Type check: clean
  • Build: clean

Test plan

  • Reproduce ENOENT with bogus shebang .js file spawned directly
  • Verify fix: same .js file spawned via process.execPath succeeds
  • Unit test: .js paths invoked via process.execPath on Unix
  • Unit test: .js paths with spaces in the path
  • Unit test: args passed correctly after the module path
  • Unit test: non-.js paths remain unchanged
  • Integration: plugins:install on standalone tarball (Linux, no system Node.js)
  • Integration: plugins:install on Windows (paths with spaces)
  • Integration: plugins:install with npm-installed CLI (system node)

@WillieRuemmele
WillieRuemmele force-pushed the wr/fixSpawnEnoentOnUnixTarballs branch from f055402 to 37bdd2e Compare August 6, 2026 15:39
@WillieRuemmele

Copy link
Copy Markdown
Author

Reproduction & Verification

Ran the actual spawn() function from src/spawn.ts against a .js file with a bogus shebang (#!/usr/bin/nonexistent-node) to simulate a standalone tarball environment where the shebang interpreter doesn't exist:

Before fix (old code with win32 guard):

Spawning .js file via our spawn() function: /tmp/repro/npm-cli.js
✗ FAILED — spawn /tmp/repro/npm-cli.js ENOENT

After fix (using process.execPath on all platforms):

Spawning .js file via our spawn() function: /tmp/repro/npm-cli.js
✓ SUCCESS — output: npm install success

The fix correctly routes .js module paths through the running Node binary (process.execPath) instead of trying to exec them directly (which relies on the shebang interpreter existing).

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.

spawn fails with ENOENT on standalone tarballs (Unix)

1 participant