Retry node shell fallback on ENOENT#85543
Conversation
|
Thanks for the context here. I did a careful shell check against current Current main and the latest inspected release already solve the central linked Linux node-exec failure at the safer gateway boundary by not forwarding gateway/default cwd to remote node execution; this PR is no longer needed as a landing path. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. So I’m closing this as already implemented rather than keeping a duplicate issue open. Review detailsBest possible solution: Keep the shipped gateway-side cwd behavior and close this branch rather than adding a node-side fallback that can silently ignore an explicitly supplied missing workdir. Do we have a high-confidence way to reproduce the issue? Yes. The linked issue evidence shows Is this the best way to solve the issue? No for this PR as a landing path. The best fix is already on main at the gateway boundary: omit gateway-derived cwd for node exec while preserving explicit node cwd values. Security review: Security review cleared: No supply-chain or security-sensitive dependency/workflow changes were introduced; the concern is redundancy and behavior fit, not a concrete security regression. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 8a5cb85c31e5; fix evidence: release v2026.6.10, commit 247a06813e01. |
|
ClawSweeper PR egg 🔥 Warming up: real-behavior proof passed; findings, security review, or rank-up moves are still in progress. Hatch commandComment Hatchability rules:
What is this egg doing here?
|
1d5c804 to
e100682
Compare
70203af to
fd0fdfb
Compare
|
@clawsweeper re-review Removed the PATH-resolved |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review Updated the Real behavior proof fields with the required plain field labels after removing the PATH fallback. |
|
🦞👀 Command router queued. I will update this comment with the next step. Re-review progress:
|
|
@clawsweeper re-review Added live Linux chroot runtime proof for the actual patched node-host runCommand path: /bin/sh absent, /usr/bin/sh present, runCommand returns stdout NODE_SHELL_FALLBACK_OK via the fallback. |
|
🦞👀 Command router queued. I will update this comment with the next step. Re-review progress:
|
494456e to
288e76c
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
288e76c to
68d2621
Compare
|
@clawsweeper re-review Updated this to address the patch-quality/security-boundary concern. The What changed:
Local proof on head
|
|
🦞🧹 I asked ClawSweeper to review this item again. |
…ENT) Linux headless node exec failed with `spawn /bin/sh ENOENT` even when /bin/sh exists (openclaw#85202). The real cause is a forwarded working directory that does not exist on the node host: Node fails the pre-exec chdir and surfaces it as `spawn <cmd> ENOENT` against the command rather than the directory. A gateway running in Docker forwards its own process.cwd() as the node workdir, which is a container path absent on the node; both /bin/sh and /usr/bin/sh point to the same dash, so swapping shells cannot help. Non-approval node exec now drops a cwd that does not resolve to a directory on the node host (falls back to the node default dir). The approval path is unchanged and still fails closed via resolveCanonicalApprovalCwdSync. The /bin/sh -> /usr/bin/sh fallback is retained for genuinely-missing shells. Adds resolveNodeExecCwd unit coverage and a /bin/sh-present + missing-cwd regression test.
68d2621 to
1209916
Compare
|
@clawsweeper re-review Reworked this around the actual root cause of the canonical issue (#85202), which the previous shell-only fallback could not address. Root cause (reproduced locally)The linked reports all show #85202 runs the gateway in Docker and the nodes as user systemd services. An unspecified node workdir defaults to the gateway's own Local repro of the exact symptom: $ node -e 'require("child_process").spawn("/bin/sh",["-lc","echo hi"],{cwd:"/does/not/exist"}).on("error",e=>console.log(e.message))'
spawn /bin/sh ENOENT # /bin/sh exists; the missing cwd is the real causeFixIn the non-approval execution path ( The new helper Tests (the
|
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
ClawSweeper applied the proposed close for this PR.
|
Summary
system.runshell execution with trusted absolute/usr/bin/shwhen the default/bin/shspawn fails with ENOENT.Fixes #85202
Why
Linux headless node hosts can report
spawn /bin/sh ENOENTeven when the node is connected andsystem.which/manual host checks show a usable shell at/usr/bin/sh. The previous node-host path treated the first spawn error as terminal, soexec host=nodefailed before trying another trusted POSIX shell path.Verification
node scripts/test-projects.mjs src/node-host/invoke.node-shell-fallback.test.ts src/infra/node-shell.test.ts src/node-host/invoke.test.ts src/node-host/invoke.sanitize-env.test.ts src/agents/bash-tools.exec-host-node.test.tspnpm tsgo:core:testgit diff --checkReal behavior proof
Behavior addressed:
Node-host
system.runno longer treats a missing default/bin/shspawn as the only possible POSIX shell path; the patched node host retries trusted absolute/usr/bin/shon ENOENT.Real environment tested:
Linux VPS source checkout at
/root/projects/openclaw-node-shell-fallback, Node.js v22.22.2, patched OpenClaw node-host runtime code at PR headfd0fdfb445. I also ran the actual patchedsrc/node-host/invoke.tsrunCommandpath inside a minimal Linux chroot proof root where/bin/shis absent and/usr/bin/sh -> dashexists.Exact steps or command run after this patch:
First ran the focused runtime/test/type gates from the patched checkout. Then ran the actual patched node-host
runCommandimplementation in a Linux chroot with an empty/bindirectory and/usr/bin/shavailable:The proof script called:
Evidence after fix:
Terminal output from the live chroot runtime proof:
Focused test output from the patched checkout:
Observed result after fix:
The actual patched node-host runtime path returned success from
/usr/bin/shwith stdoutNODE_SHELL_FALLBACK_OKwhen invoked in a Linux root where/bin/shwas absent and/usr/bin/shexisted. The focused regression separately asserts the retry sequence:What was not tested:
I still do not have the reporter's exact paired Linux headless node/systemd setup connected to this gateway, so this is runtime proof of the patched node-host command path under the same missing-
/bin/shfailure condition, not a full paired-nodeexec host=nodeend-to-end recording from the original environment.