openclaw - ✅(Solved) Fix Benchmark spawner scripts use bare "node" instead of process.execPath, risking version mismatch [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#83921Fetched 2026-05-20 03:46:39
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
1
Timeline (top)
labeled ×5commented ×1cross-referenced ×1unsubscribed ×1

Fix Action

Fix / Workaround

Severity: medium / Confidence: high / Category: bug Triage: confirmed-bug Detected against: openclaw v2026.5.18 (latest stable at time of scan, 2026-05-18) Tooling: clawpatch 0.3.0 + acpx/claude-sonnet-4-5 via Brad Mills protocol


Standardized clawpatch finding. Persistent in v2026.5.18 (not resolved by upgrading from v2026.5.12). Finding ID: fnd_sig-feat-cli-command-23edfe2554-_2dbd4973be.

PR fix notes

PR #84304: fix(scripts): spawn bench runners under process.execPath (#83921)

Description (problem / solution / changelog)

Fixes #83921.

scripts/test-cli-startup-bench-budget.mjs:108 and scripts/test-update-cli-startup-bench.mjs:67 both invoked spawnSync("node", args, …). The first argument is resolved through PATH. In environments using version managers (nvm, fnm, volta, asdf) the PATH-resolved node is a shim that may resolve to a different Node version than the one currently executing the parent script. The bench runner can then run on Node X while the parent runs on Node Y — measurements stop being comparable to the baseline, and the fixture-updater writes a fixture that no other run can reproduce.

The sibling scripts scripts/bench-cli-startup.ts and scripts/check-cli-startup-memory.mjs already use process.execPath for exactly this reason. The inconsistency is what the issue calls out as subtle: the underlying bench harness uses process.execPath for the CLI-under-test, but the runner / updater that drives it doesn't.

Changes

  • scripts/test-cli-startup-bench-budget.mjs: change spawnSync("node", args, …) to spawnSync(process.execPath, args, …) in resolveCurrentReportPath's spawn block. Inline comment cites the sibling pattern in bench-cli-startup.ts / check-cli-startup-memory.mjs and the issue.
  • scripts/test-update-cli-startup-bench.mjs: identical change in the top-level spawn at line 67.

Diff stat: 2 files, +13 / -2. No package.json, dependency, or interface change.

Real behavior proof

  • Behavior or issue addressed: Sanitized issue evidence — process.execPath is always the absolute path of the currently-executing Node binary, regardless of PATH state. The OpenClaw scripts dir already uses this pattern at bench-gateway-startup.ts:842, bench-gateway-restart.ts:1285, write-cli-startup-metadata.ts:208,246, openclaw-npm-postpublish-verify.ts:581, and bench-cli-startup.ts.

  • Real environment tested: Local Node 22.x running under nvm (/home/<user>/.nvm/versions/node/v22.22.0/bin/node) — the exact polyglot environment the issue's reproduction step calls out. Probe at /tmp/probe_83921.mjs does both halves of the proof. (a) Parses both patched scripts and verifies (i) spawnSync(process.execPath, args appears in each, (ii) no spawnSync("node", args calls remain. (b) Replays the structural difference between PATH-resolved node and process.execPath on the test machine — confirms process.execPath is an absolute path (immune to PATH/shim drift), that running spawnSync(process.execPath, ["--version"]) returns a valid version string, and that the sibling script bench-cli-startup.ts already uses the same pattern.

  • Exact steps or command run after this patch: node /tmp/probe_83921.mjs

  • Evidence after fix:

PASS: test-cli-startup-bench-budget.mjs uses process.execPath as the spawn binary
PASS: no remaining bare-'node' spawnSync in test-cli-startup-bench-budget.mjs
PASS: test-update-cli-startup-bench.mjs uses process.execPath as the spawn binary
PASS: no remaining bare-'node' spawnSync in test-update-cli-startup-bench.mjs
PASS: process.execPath is an absolute path (/home/.../v22.22.0/bin/node) — immune to PATH/shim drift
PASS: spawnSync(process.execPath, ['--version']) returned v22.22.0 — verified runnable
PASS: sibling bench-cli-startup.ts uses process.execPath in 1 location(s) — pattern mirrored correctly
  • Observed result after fix: Both bench runners now spawn the child Node process under the same binary as the parent, eliminating the version-mismatch class of bug entirely. No behavior change on systems where node (PATH) and process.execPath already agree (e.g., system Node, single-version Docker images).

  • What was not tested: A live multi-version nvm switch demonstrating the buggy shape — the issue's repro requires nvm shell activation pointing to a different version than the parent script. The probe demonstrates the structural mechanism that makes the bug impossible (absolute-path-driven spawn rather than PATH lookup), which is the actual fix being made.

Audit (per CLAUDE rules — all 5 steps)

  • Existing-helper check: process.execPath is the codebase's canonical answer to this concern — already used in 5+ sibling scripts including bench-cli-startup.ts, bench-gateway-startup.ts, bench-gateway-restart.ts, check-cli-startup-memory.mjs, write-cli-startup-metadata.ts. The fix is "use the existing primitive" not "add a helper." PASS
  • Shared-helper caller check: These are top-level scripts not imported by anything. The spawn argument change is local to the script's own main flow. PASS
  • Broader-fix rival scan: gh pr list --search '83921 in:title,body' and gh pr list --search 'spawnSync node process.execPath' return no open PRs. Issue timeline shows zero cross-references. PASS
  • Recent-merge audit: git log --oneline -3 -- scripts/test-cli-startup-bench-budget.mjs scripts/test-update-cli-startup-bench.mjs shows e1061a8b46 test(live): tolerate provider drift in release checks — unrelated. PASS
  • Prototype-pollution scan: N/A — first-argument swap on spawnSync.

Changed files

  • scripts/test-cli-startup-bench-budget.mjs (modified, +7/-1)
  • scripts/test-update-cli-startup-bench.mjs (modified, +6/-1)

Code Example

const run = spawnSync("node", args, {
    cwd: process.cwd(),
    stdio: "inherit",
    env: process.env,
  });

---

const run = spawnSync("node", args, {
  cwd: process.cwd(),
  stdio: "inherit",
  env: process.env,
});
RAW_BUFFERClick to expand / collapse

Severity: medium / Confidence: high / Category: bug Triage: confirmed-bug Detected against: openclaw v2026.5.18 (latest stable at time of scan, 2026-05-18) Tooling: clawpatch 0.3.0 + acpx/claude-sonnet-4-5 via Brad Mills protocol

Evidence

  • scripts/test-cli-startup-bench-budget.mjs:88-97 (resolveCurrentReportPath)
const run = spawnSync("node", args, {
    cwd: process.cwd(),
    stdio: "inherit",
    env: process.env,
  });
  • scripts/test-update-cli-startup-bench.mjs:46-52 (None)
const run = spawnSync("node", args, {
  cwd: process.cwd(),
  stdio: "inherit",
  env: process.env,
});

Reasoning

Both scripts call spawnSync("node", ...) which resolves "node" through PATH. In environments using version managers (nvm, fnm, volta, asdf), the PATH-resolved "node" may differ from the Node.js instance currently executing the script (process.execPath). This means the bench runner and the fixture updater could execute bench-cli-startup.ts on a different Node version than intended, producing measurements that are not comparable to the baseline or to what CI uses. bench-cli-startup.ts itself correctly uses process.execPath when spawning the CLI under test, making the inconsistency more subtle.

Reproduction

Use nvm to set node 20 as default, then run the scripts while nvm shell activation points to node 22 — the spawned bench will run on node 20 while the parent runs on node 22.

Recommendation

Replace spawnSync("node", args, ...) with spawnSync(process.execPath, args, ...) in both scripts, matching the pattern used in bench-cli-startup.ts and check-cli-startup-memory.mjs.

Why existing tests miss this

No tests exist for these scripts. The version mismatch only becomes visible in polyglot Node environments.

Minimum fix scope

Change the first argument of spawnSync from "node" to process.execPath in scripts/test-cli-startup-bench-budget.mjs (resolveCurrentReportPath) and scripts/test-update-cli-startup-bench.mjs.


Standardized clawpatch finding. Persistent in v2026.5.18 (not resolved by upgrading from v2026.5.12). Finding ID: fnd_sig-feat-cli-command-23edfe2554-_2dbd4973be.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Benchmark spawner scripts use bare "node" instead of process.execPath, risking version mismatch [1 pull requests, 1 comments, 2 participants]