* fix(update): explain runtime and global install permission failures
Report the affected directory, owner, and next action for npm permission
failures. Preserve typed outcomes in dry-run previews, update reports, and
Doctor history, and give candidate-specific Node upgrade guidance.
Thanks to @arrobapontocom-ui for reporting the upgrade diagnostics in #150452.
* fix(update): keep the final retry error in staging and guidance
Carry the package owner's failedStep through the result adapter instead of
selecting a failure from attempt history. Admission, settlement, and retention
owners record their selected outcomes directly.
Preserve EACCES remediation and facts after an unrelated npm failure and retry.
Thanks to @arrobapontocom-ui for the report in #150452; follow-up to #150526.
* fix(update): preserve deployment advice in permission recovery
* test(update): assert candidate runtime guidance at the CLI boundary
* fix(update): recommend a runtime the updater itself can run
* fix(update): keep the CLI reachable through a runtime switch in recovery guidance
* fix(update): recheck ownership after runtime switches
Continue through the retained absolute launcher instead of recommending an
uninspected global install. Recheck prefix and service ownership, preserve
typed refusal guidance in reports, and keep the selected runtime during
fresh-profile admission.
Thanks to @arrobapontocom-ui for the original report (#150452, item 1).
* fix(update): isolate the global command runner contract
* test(update): match resolved npm prefix probes
* fix(update): refuse uninspectable npm destinations
* fix(runtime): keep diagnostics and update usable on an unsupported Node
Share CLI admission between the launcher and source guard, retain private-copy
SQLite recovery, and keep live database writers and repair agents refused.
Route plain Doctor to lint and refuse update before its run-ledger admission
when the CLI Node is unsupported. Report CLI/service runtime findings and the
reporting Node version in update-failure reports.
Refs #140672#142742
* docs(install): explain private Node recovery and diagnostic access
* test(runtime): preserve Node recovery coverage with diagnostic admission
* fix(runtime): offer Node recovery once per update invocation
* fix(build): emit Node 22 syntax for recovery diagnostics
* fix(update): check runtime at the state preparation boundary
* fix(doctor): preserve migration order before runtime diagnostics
* fix(runtime): recover before admitting unsupported Node diagnostics
* fix(runtime): preserve capability admission in diagnostic recovery
* test(cli): retain capability checks in startup fixtures
* refactor(runtime): share Node findings across diagnostic commands
* fix(doctor): omit absent repair hints in lint errors
* fix(runtime): require Node builds with lossless SQLite reads
* fix(runtime): preserve upgrades and guard sealed workers
Validate downloaded Node before switching the active runtime alias, reject unsupported sealed-worker runtimes, and keep the Gateway error fixture on a supported Node release. Document the approved ARMv7 and older macOS compatibility losses and decoder fix boundaries.
* test(runtime): use typed process exports in worker fixture
* test(runtime): align installer fixtures without growing test shards
* test(runtime): align release and guest runtime fixtures
* fix(test): canonicalize Windows temp roots for Node 24
Expand Windows short paths before creating test directories and owned child environments. Node 24 filesystem watchers otherwise abort when native long event paths differ from inherited short temporary paths. Preserve explicit custom-root spelling and existing cleanup ownership.
* test(ci): run Windows temp-root regressions in the native lane
* fix(daemon): stop reporting failed runtime probes as unsupported runtimes
The daemon runtime probe wrapped its exec in a bare catch that returned
`supported: false`, so any failure to *run* the probe was laundered into a
verdict that the runtime itself was unsupported. Operators on a perfectly
good Node install were told to install a Node version they already had.
Observed on Ubuntu 26.04 with Node 26.8.1: `openclaw node install` failed
with "No supported Node runtime was selected for the daemon" whenever the
process cwd was not readable by the service user (e.g. `runuser -u openclaw`
inheriting root's 0700 home over SSH), because every child spawn then fails
EACCES. The version logic was never wrong -- resolveSystemNodeInfo returned
supported:true and resolvePreferredNodePath returned /usr/bin/node when
probed directly on the affected host.
Node and Bun probes now share one resolver returning a closed
supported | unsupported | probe-failed union. A failed probe retains its
cause, executable, and cwd, and selection propagates that instead of falling
through to Node-upgrade advice.
Also:
- Derive the supported-version wording from NODE_RELEASE_FLOORS via a new
exported SUPPORTED_NODE_VERSIONS, replacing six hand-copied spellings that
omitted the >=25.9.0 line and told operators to downgrade.
- Forward OPENCLAW_WRAPPER through the node-host install path; the documented
escape hatch was previously gateway-daemon-only.
Production LOC net +6 (+156/-150); consolidating the duplicated Node/Bun
probes paid for the new failure handling.
* docs(cli): drop machine-local path from node probe-failure guidance
ClawSweeper P3: docs/AGENTS.md requires generic docs content with no local
paths. The probe-failure recovery example prescribed a specific directory;
state the readability requirement instead.