openclaw - ✅(Solved) Fix [Bug]: `openclaw doctor` emits 3 redundant "Gateway runtime" panels and the third one falsely says "Node 22 LTS or Node 24 not found" when nvm Node 22 is found and in use [2 pull requests, 2 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#78676Fetched 2026-05-07 03:33:58
View on GitHub
Comments
2
Participants
2
Timeline
6
Reactions
2
Author
Timeline (top)
commented ×2cross-referenced ×2labeled ×1referenced ×1

openclaw doctor prints three separate ◇ Gateway runtime panels for a single Node-version condition, and the third panel is contradictory: it says "System Node 22 LTS (22.14+) or Node 24 not found" while the first panel of the same run announces it is using ~/.nvm/versions/node/v22.22.2/bin/node for the daemon.

Root Cause

  • Affected: any user whose system Node is below 22.14+ and who has a working Node 22+ from nvm / asdf / fnm / volta (i.e. the typical Linux/dev-machine configuration). Reproduced on Ubuntu 24.04 + nvm; the same code paths run on macOS/Windows.
  • Severity: Low–Medium. Annoying / confusing UX, not blocking. Common-user-visible because every doctor run shows it.
  • Frequency: Always, on every openclaw doctor invocation in the affected layout.
  • Consequence: Users following the third panel's advice ("Install Node 22 LTS via Homebrew/apt/choco") may wipe or shadow a working nvm Node 22 chain that doctor itself just reported as "Using … for the daemon." At minimum it costs time chasing a non-issue and undermines trust in the doctor output.

Fix Action

Fix / Workaround

openclaw -> claude-cli. Not relevant to the defect; the panels are emitted by the doctor command before any model dispatch.

PR fix notes

PR #78682: fix(doctor): emit one Gateway runtime note instead of three (#78676)

Description (problem / solution / changelog)

Problem

On a host where the system Node is below 22.14 but a version-manager Node (nvm v22.22.2) is in use, openclaw doctor prints three consecutive ◇ Gateway runtime panels, one of which falsely claims "System Node 22 LTS or Node 24 not found" while the first panel already announced the daemon is using the nvm Node.

Traced in the issue to src/commands/doctor-gateway-services.ts lines 425-433: when !systemNodePath (system Node below threshold), two sequential notes fired:

  1. renderSystemNodeWarning(systemNodeInfo) → "System Node 20.x is below required 22.14+…"
  2. Unconditional hardcoded note → "System Node 22 LTS (22.14+) or Node 24 not found…"

The second note contradicts the first: the system Node was found, just too old. The "not found" text only makes sense when resolveSystemNodeInfo returned null.

Fixes #78676.

Fix

Collapse the two notes into one via null-coalescing:

// before
const warning = renderSystemNodeWarning(systemNodeInfo);
if (warning) {
  note(warning, "Gateway runtime");
}
note(
  "System Node 22 LTS (22.14+) or Node 24 not found. Install via Homebrew/apt/choco…",
  "Gateway runtime",
);

// after
const warning = renderSystemNodeWarning(systemNodeInfo)
  ?? "System Node 22 LTS (22.14+) or Node 24 not found. Install via Homebrew/apt/choco…";
note(warning, "Gateway runtime");
  • When systemNodeInfo is null: renderSystemNodeWarning returns null → fallback "not found" text fires. One note.
  • When systemNodeInfo.supported === false: renderSystemNodeWarning returns the "below required" message → no fallback. One note.

Audit A — existing helper check

No separate deduplication helper exists. The renderSystemNodeWarning function itself is already the canonical message renderer; wiring it through ?? is the minimal composable approach.

Audit B — shared caller check

renderSystemNodeWarning is called in 3 files (doctor-gateway-services.ts, daemon-install-runtime-warning.ts, runtime-paths.ts). This change only touches the doctor-gateway-services.ts call site and does not alter the function signature or behavior.

Audit C — rival PR scan

No rival PR open for #78676 at scout time.

Real behavior proof

New tests in doctor-gateway-services.test.ts:

  • "emits exactly one Gateway runtime note when system Node is below minimum" — asserts mocks.note called once with "Gateway runtime" title and message containing "below the required Node 22.14+"
  • "emits the not-found note when resolveSystemNodeInfo returns null" — asserts one "Gateway runtime" note containing "not found"

All 26 tests pass. pnpm -s tsgo:core clean.

Co-authored-by: hclsys

Changed files

  • CHANGELOG.md (modified, +2/-0)
  • src/commands/doctor-gateway-services.test.ts (modified, +87/-0)
  • src/commands/doctor-gateway-services.ts (modified, +44/-28)

PR #78688: fix(doctor): collapse duplicate Gateway runtime panels and stop false…

Description (problem / solution / changelog)

Summary

  • Problem: openclaw doctor emits three Gateway runtime panels for a single Node-version condition. Panel 2 is a strict-subset duplicate of Panel 1 (renderSystemNodeWarning(systemNodeInfo) re-fired without selectedNodePath). Panel 3 unconditionally claims "System Node 22 LTS (22.14+) or Node 24 not found" whenever the system Node is unsupported — even when Panel 1 in the same run announced "Using ~/.nvm/versions/node/v22.22.2/bin/node for the daemon."
  • Why it matters: This is the typical Linux/dev-machine layout (system Node old, version-manager Node 22 fine). Every doctor run shows three overlapping notes ending in a factually wrong one. Users following Panel 3's advice ("Install Node 22 LTS via Homebrew/apt/choco") may shadow or wipe a working nvm Node 22 chain that doctor itself just reported as in-use.
  • What changed: In src/commands/doctor-gateway-services.ts, drop the local renderSystemNodeWarning(systemNodeInfo) re-emit (Panel 2 — emitDaemonInstallRuntimeWarning at daemon-install-helpers.ts already covers it via Panel 1, with full selectedNodePath context), and gate the "not found" note on resolvePreferredNodePath({ runtime: "node" }) returning undefined rather than on !systemNodePath. The "not found" message now only fires when no Node 22+ is reachable anywhere — system Node, current process, or any version manager.
  • What did NOT change (scope boundary): renderSystemNodeWarning itself, resolveSystemNodeInfo, resolvePreferredNodePath, the existing emit at daemon-install-helpers.ts (Panel 1, which is correct), the wording of the "not found" string, the needsNodeRuntimeMigration audit signal, and the Bun-runtime path (still skipped by emitNodeRuntimeWarning's runtime !== "node" early return).

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #78676
  • Related #78682 (parallel attempt by another contributor; collapses Panels 2 + 3 only — the Panel 1 ↔ Panel 2 duplicate persists in their fix because they keep renderSystemNodeWarning(systemNodeInfo) firing on the doctor side, where emitDaemonInstallRuntimeWarning is already producing the same warning. This PR drops Panel 2 entirely and gates Panel 3 on resolvePreferredNodePath, taking the bug scenario from 3 panels to 1.)
  • This PR fixes a bug or regression

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Triple Gateway runtime panel emission with contradictory "Node 22 LTS or Node 24 not found" message in openclaw doctor — see #78676.
  • Real environment tested: Ubuntu 24.04 (Linux 6.8.0-110-generic). System Node /usr/bin/node reports v20.20.2 (below 22.14, the audit-triggering case). Version-manager Node ~/.nvm/versions/node/v22.22.2/bin/node is on PATH. OpenClaw source checkout at this branch tip rebased onto upstream 1f822d7c22. Local commit SHA on this run: 69d3253 (matches the 🦞 OpenClaw 2026.5.6 (69d3253) banner in the capture below).
  • Exact steps or command run after this patch:
    1. export PATH="$HOME/.nvm/versions/node/v22.22.2/bin:$PATH"
    2. pnpm openclaw doctor --non-interactive
  • Evidence after fix (terminal capture, redacted to the relevant panels):
🦞 OpenClaw 2026.5.6 (69d3253)

┌  OpenClaw doctor
◇  Gateway service config ─────────────────────────────────────────────────╮
│  Gateway service entrypoint resolves to a source checkout:               │
│  /home/orin/Gittensor/Test/openclaw.                                     │
│  Run `openclaw doctor --fix` from the intended package install, or       │
│  reinstall the gateway service with `openclaw gateway install --force`.  │
├──────────────────────────────────────────────────────────────────────────╯
◇  Gateway runtime ───────────────────────────────────────────────────────╮
│  System Node 20.20.2 at /usr/bin/node is below the required Node        │
│  22.14+. Using /home/orin/.nvm/versions/node/v22.22.2/bin/node for the  │
│  daemon. Install Node 24 (recommended) or Node 22 LTS from nodejs.org   │
│  or Homebrew.                                                           │
├─────────────────────────────────────────────────────────────────────────╯
◇  Gateway service config ─────────────────────────────────────────────────╮
│  - Gateway service PATH includes version managers or package managers;   │
│    recommend a minimal PATH.                                             │
│    (/home/orin/.nvm/versions/node/v22.22.2/bin,                          │
  • Observed result after fix: Exactly one ◇ Gateway runtime panel in the doctor output, containing the "Using <version-manager-path> for the daemon" context. No duplicate panel. No spurious "Node 22 LTS or Node 24 not found" panel. The next section (Gateway service config) is unrelated and unaffected by this PR.
  • Before evidence: see the verbatim three-panel capture in the issue body of #78676 (same host, same /usr/bin/node v20.20.2 + nvm v22.22.2 layout).
  • What was not tested:
    • macOS Homebrew Node fallback (no macOS host available locally; the same resolvePreferredNodePath helper is what buildGatewayInstallPlan already uses to pick the runtime, so its cross-platform behavior is exercised in the broader install path).
    • Windows + nvm-windows / WSL.
    • asdf, fnm, volta version managers (only nvm reproduced on this host).

Root Cause (if applicable)

  • Root cause: Two stacked bugs in maybeRepairGatewayServiceConfig (src/commands/doctor-gateway-services.ts):
    1. renderSystemNodeWarning(systemNodeInfo) was called without selectedNodePath, even though buildGatewayInstallPlan (run earlier in the same function via buildExpectedGatewayServicePlan) had already invoked emitDaemonInstallRuntimeWarning with the resolved programArguments[0] as selectedNodePath. Two Gateway runtime panels with the same first sentence resulted, the second one a strict subset of the first.
    2. The "not found" note was gated on !systemNodePath, computed as systemNodeInfo?.supported ? systemNodeInfo.path : null — i.e., only the system Node binary, ignoring version-managed Node entirely. The note fired whenever the system Node was below 22.14, regardless of whether a version-manager Node 22+ was already in use.
  • Missing detection / guardrail: No regression test asserted "this function should not emit a Gateway runtime note when emitDaemonInstallRuntimeWarning already covered the runtime case." The two new tests in this PR lock in that contract.
  • Contributing context (if known): The doctor-side renderSystemNodeWarning call predates emitDaemonInstallRuntimeWarning being added to buildGatewayInstallPlan. After that helper started covering the runtime warning, the doctor-side call became redundant but was never removed.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/commands/doctor-gateway-services.test.ts (two new it(...) cases inside the existing maybeRepairGatewayServiceConfig describe block).
  • Scenario the test should lock in:
    1. needsNodeRuntimeMigration=true, resolveSystemNodeInfo returns an unsupported { path: "/usr/bin/node", version: "20.20.2", supported: false }, resolvePreferredNodePath returns the nvm Node 22 path → expect zero Gateway runtime notes from maybeRepairGatewayServiceConfig.
    2. Same audit/system-node fixtures, but resolvePreferredNodePath returns undefined → expect exactly one Gateway runtime note containing "not found".
  • Why this is the smallest reliable guardrail: the bug is purely about which note(...) calls fire and with what gate. A unit test driving note calls through the existing mock surface is sufficient; a seam or e2e test would add scaffolding without catching anything the unit cannot.
  • Existing test that already covers this (if any): None — doctor-gateway-services.test.ts had no coverage of the Gateway runtime panel emission paths before this PR.
  • If no new test is added, why not: N/A (added).

User-visible / Behavior Changes

In the reported configuration (system Node below 22.14 + version-manager Node 22+ in use):

  • Before: three ◇ Gateway runtime panels per openclaw doctor run — the third claiming "Node 22 LTS or Node 24 not found" while the first showed the daemon was using nvm Node 22.
  • After: one ◇ Gateway runtime panel per run, with the correct "Using <version-manager-path> for the daemon" context.

When no Node 22+ is reachable anywhere (system, current process, or any version manager), the existing "Node 22 LTS or Node 24 not found" message still fires — its content and wording are unchanged, only the gate is corrected.

No config or default behavior changes elsewhere.

Diagram (if applicable)

Bug scenario: system Node 20 + nvm Node 22 in use

Before:
openclaw doctor
  └── Gateway runtime  (Panel 1 — "Using ~/.nvm/...node for the daemon. ...")
  └── Gateway runtime  (Panel 2 — same as Panel 1 minus the "Using" sentence)
  └── Gateway runtime  (Panel 3 — "Node 22 LTS or Node 24 not found"  ← contradicts Panel 1)

After:
openclaw doctor
  └── Gateway runtime  (Panel 1 — unchanged; "Using ~/.nvm/...node for the daemon. ...")

No-Node-22-anywhere scenario:

Before:                       After:
  Gateway runtime (Panel 1)     Gateway runtime (Panel 1)
  Gateway runtime (Panel 2)     Gateway runtime ("not found"; gated on resolvePreferredNodePath === undefined)
  Gateway runtime (Panel 3)

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A — the change is a wording / dedup adjustment in a diagnostics output path.

Repro + Verification

Environment

  • OS: Ubuntu 24.04 (Linux 6.8.0-110-generic)
  • Runtime/container: Node v22.22.2 via nvm (system /usr/bin/node is v20.20.2 — the unsupported case the bug describes)
  • Model/provider: claude-cli runtime (default agent); the bug is independent of model dispatch
  • Integration/channel (if any): N/A — pre-runtime diagnostics path
  • Relevant config (redacted): default-shape config with a single claude-cli auth profile; no special doctor or gateway flags

Steps

  1. Ensure system Node is below 22.14 (e.g., /usr/bin/node reports v20.20.2) and a version-manager Node ≥ 22.14 is on PATH (e.g., ~/.nvm/versions/node/v22.22.2/bin/node).
  2. From a source checkout: pnpm install --frozen-lockfile.
  3. pnpm openclaw doctor --non-interactive and observe the Gateway runtime panel section.

Expected

  • Exactly one ◇ Gateway runtime panel, containing the "Using <version-manager-path> for the daemon" context.
  • No "Node 22 LTS or Node 24 not found" line in this scenario.

Actual (after this patch — matches expected)

  • One ◇ Gateway runtime panel with the "Using …nvm…" context (verbatim capture in the Real-behavior-proof section above).
  • Doctor proceeds to its normal next sections without the spurious "not found" note.

Evidence

  • Failing test/log before + passing after — pnpm test src/commands/doctor-gateway-services.test.ts reports 26 passed (24 pre-existing + 2 new). Without the source change, the new tests fail (Panel 2 still fires unconditionally).
  • Trace/log snippets
  • Screenshot/recording — fenced terminal capture from pnpm openclaw doctor --non-interactive is in the Real-behavior-proof section above.
  • Perf numbers (if relevant) — N/A.

Human Verification (required)

  • Verified scenarios:
    • System Node 20.20.2 + nvm Node 22.22.2 in use → 1 panel after fix (3 panels before fix), captured in this PR body.
    • pnpm test src/commands/doctor-gateway-services.test.ts → 26/26 pass on Node 22.22.2.
    • pnpm check:changed → green on touched lanes (core test typecheck + extension test typecheck).
    • pnpm exec oxfmt --check --threads=1 src/commands/doctor-gateway-services.ts src/commands/doctor-gateway-services.test.ts → clean.
  • Edge cases checked:
    • "No Node 22+ anywhere" path — the existing "not found" message still fires (covered by the second new unit test).
    • Bun-runtime path — emitDaemonInstallRuntimeWarning early-returns on runtime !== "node" (existing behavior, unchanged).
  • What you did not verify:
    • macOS Homebrew Node fallback (no macOS host available locally — same resolvePreferredNodePath helper drives buildGatewayInstallPlan's runtime pick, exercised in the broader install path).
    • Windows + nvm-windows / WSL.
    • asdf, fnm, volta version managers (only nvm reproduced).

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: N/A.

Risks and Mitigations

  • Risk: The new gate uses resolvePreferredNodePath from daemon/runtime-paths.js, which performs a which/where PATH lookup. On a host where the lookup raises (rare — already exercised by the existing install path), the doctor branch could differ in error shape.
    • Mitigation: buildGatewayInstallPlan (which fires earlier in the same function via buildExpectedGatewayServicePlan) already calls resolvePreferredNodePath indirectly through resolveDaemonInstallRuntimeInputs. If that resolution would error, doctor would have errored before reaching the new gate. The new call is therefore a no-op-cost duplicate on a happy path and equally fail-fast on a sad path.
  • Risk: The "not found" message no longer fires in the Bun-runtime + nvm Node 22 case (audit flags Bun migration, system Node old, but a usable Node 22 exists). The user keeps the actionable Bun → Node migration prompt from the regular audit issues path; the redundant "Node not found" prompt is suppressed.
    • Mitigation: This is the intended behavior — Panel 3 should not claim "not found" when a Node 22+ binary is reachable. The audit's gatewayRuntimeBun issue still surfaces through the standard audit.issues.length flow further down the same function.

Changed files

  • src/commands/doctor-gateway-services.test.ts (modified, +82/-1)
  • src/commands/doctor-gateway-services.ts (modified, +10/-8)

Code Example

pnpm openclaw doctor

---

Gateway runtime ───────────────────────────────────────────────────────╮
System Node 20.20.2 at /usr/bin/node is below the required Node22.14+. Using /home/orin/.nvm/versions/node/v22.22.2/bin/node for the  │
│  daemon. Install Node 24 (recommended) or Node 22 LTS from nodejs.org│  or Homebrew.                                                           
├─────────────────────────────────────────────────────────────────────────╯

---

Gateway runtime ──────────────────────────────────────────────────────╮
System Node 20.20.2 at /usr/bin/node is below the required Node22.14+. Install Node 24 (recommended) or Node 22 LTS from nodejs.org│  or Homebrew.                                                          
├────────────────────────────────────────────────────────────────────────╯

---

Gateway runtime ────────────────────────────────────────────────╮
System Node 22 LTS (22.14+) or Node 24 not found. Install via   │
Homebrew/apt/choco and rerun doctor to migrate off Bun/version  │
│  managers.                                                       
├──────────────────────────────────────────────────────────────────╯

---

Verbatim doctor output (trimmed to the affected region):


Gateway service config ─────────────────────────────────────────────────╮
Gateway service entrypoint resolves to a source checkout:/home/orin/Gittensor/Test/openclaw.                                     
Run `openclaw doctor --fix` from the intended package install, or       │
│  reinstall the gateway service with `openclaw gateway install --force`.  
├──────────────────────────────────────────────────────────────────────────╯
Gateway runtime ───────────────────────────────────────────────────────╮
System Node 20.20.2 at /usr/bin/node is below the required Node22.14+. Using /home/orin/.nvm/versions/node/v22.22.2/bin/node for the  │
│  daemon. Install Node 24 (recommended) or Node 22 LTS from nodejs.org│  or Homebrew.                                                           
├─────────────────────────────────────────────────────────────────────────╯
Gateway runtime ──────────────────────────────────────────────────────╮
System Node 20.20.2 at /usr/bin/node is below the required Node22.14+. Install Node 24 (recommended) or Node 22 LTS from nodejs.org│  or Homebrew.                                                          
├────────────────────────────────────────────────────────────────────────╯
Gateway runtime ────────────────────────────────────────────────╮
System Node 22 LTS (22.14+) or Node 24 not found. Install via   │
Homebrew/apt/choco and rerun doctor to migrate off Bun/version  │
│  managers.                                                       
├──────────────────────────────────────────────────────────────────╯


Source pointers:

- `src/commands/daemon-install-helpers.ts:524-530` — first emit site (`emitDaemonInstallRuntimeWarning`, title `"Gateway runtime"`).
- `src/commands/doctor-gateway-services.ts:425-434` — second + third emit sites (`renderSystemNodeWarning(systemNodeInfo)` then an unconditional `note("System Node 22 LTS ... not found ...", "Gateway runtime")`).
- `src/daemon/runtime-paths.ts:181-191``renderSystemNodeWarning(systemNode, selectedNodePath?)`. The "Using `<path>` for the daemon" sentence is gated on `selectedNodePath`; the doctor-side call site does not pass it, which is why Panels 1 and 2 differ only by that sentence.

`openclaw status` confirms the very same daemon is up and using the same nvm Node 22 (Slack channel `OK`, sessions running on `claude-opus-4-7`). So the third panel's "not found" is provably incorrect at the same instant.
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

openclaw doctor prints three separate ◇ Gateway runtime panels for a single Node-version condition, and the third panel is contradictory: it says "System Node 22 LTS (22.14+) or Node 24 not found" while the first panel of the same run announces it is using ~/.nvm/versions/node/v22.22.2/bin/node for the daemon.

Steps to reproduce

  1. On a host where the system Node (e.g. /usr/bin/node) is below 22.14 (here v20.20.2) and a usable Node ≥ 22.14 is available via a version manager such as nvm (here ~/.nvm/versions/node/v22.22.2/bin/node).

  2. Make sure the version-manager Node is on PATH so the OpenClaw CLI can launch (e.g. export PATH=/home/<user>/.nvm/versions/node/v22.22.2/bin:$PATH).

  3. From a current install on main (reproduced on 2026.5.5 at commit e28ad6a869), run:

    pnpm openclaw doctor
  4. Observe three consecutive ◇ Gateway runtime panels in the doctor output.

Expected behavior

A single Gateway runtime panel that explains the situation once: system Node is below the minimum, OpenClaw is falling back to the version-manager Node it actually uses, and what the user can do about it. No panel should claim Node 22 LTS is "not found" when a supported Node 22 binary was discovered and is being used by the daemon.

Actual behavior

Three ◇ Gateway runtime panels appear in one openclaw doctor run, under the same heading, with overlapping and partly contradictory text.

Panel 1 (correct, contextual):

◇  Gateway runtime ───────────────────────────────────────────────────────╮
│  System Node 20.20.2 at /usr/bin/node is below the required Node        │
│  22.14+. Using /home/orin/.nvm/versions/node/v22.22.2/bin/node for the  │
│  daemon. Install Node 24 (recommended) or Node 22 LTS from nodejs.org   │
│  or Homebrew.                                                           │
├─────────────────────────────────────────────────────────────────────────╯

Panel 2 (same first sentence, drops the "Using nvm Node…" context):

◇  Gateway runtime ──────────────────────────────────────────────────────╮
│  System Node 20.20.2 at /usr/bin/node is below the required Node       │
│  22.14+. Install Node 24 (recommended) or Node 22 LTS from nodejs.org  │
│  or Homebrew.                                                          │
├────────────────────────────────────────────────────────────────────────╯

Panel 3 (factually misleading — Node 22.22.2 IS found and IS in use, panel asserts it is not found):

◇  Gateway runtime ────────────────────────────────────────────────╮
│  System Node 22 LTS (22.14+) or Node 24 not found. Install via   │
│  Homebrew/apt/choco and rerun doctor to migrate off Bun/version  │
│  managers.                                                       │
├──────────────────────────────────────────────────────────────────╯

Tracing the three panels back to source (current main, e28ad6a869):

  • Panel 1 comes from src/commands/daemon-install-helpers.ts:524 calling emitDaemonInstallRuntimeWarning (via buildGatewayInstallPlan), which passes the resolved nvm nodePath to renderSystemNodeWarning, producing the variant with "Using … for the daemon."
  • Panel 2 comes from src/commands/doctor-gateway-services.ts:426 (renderSystemNodeWarning(systemNodeInfo)), which is called without selectedNodePath, producing the same warning as Panel 1 but without the "Using nvm Node" sentence.
  • Panel 3 comes from src/commands/doctor-gateway-services.ts:430-433, which unconditionally appends a second note(..., "Gateway runtime") whose text says Node 22 LTS / Node 24 is "not found" whenever !systemNodePath — but this branch only checks the system Node, not the version-manager Node that doctor itself reports as "Using" one panel above.

Net effect: in the single most common Linux install layout (system Node old, nvm Node 22 fine), doctor advertises three "Gateway runtime" notes about the same condition, and the third one tells the user something that is the opposite of what the first one just said.

OpenClaw version

2026.5.5 (commit e28ad6a869, latest origin/main at time of report)

Operating system

Ubuntu 24.04 (Linux 6.8.0-110-generic)

Install method

Source checkout / pnpm openclaw … from a local clone of openclaw/openclaw.

Model

anthropic/claude-opus-4-7 via claude-cli runtime (default agent). Bug is independent of model — it is a doctor diagnostic emit-path issue.

Provider / routing chain

openclaw -> claude-cli. Not relevant to the defect; the panels are emitted by the doctor command before any model dispatch.

Additional provider/model setup details

Not relevant. The defect reproduces on a default-shape config with only a claude-cli auth profile.

Logs, screenshots, and evidence

Verbatim doctor output (trimmed to the affected region):


◇  Gateway service config ─────────────────────────────────────────────────╮
│  Gateway service entrypoint resolves to a source checkout:               │
│  /home/orin/Gittensor/Test/openclaw.                                     │
│  Run `openclaw doctor --fix` from the intended package install, or       │
│  reinstall the gateway service with `openclaw gateway install --force`.├──────────────────────────────────────────────────────────────────────────╯
◇  Gateway runtime ───────────────────────────────────────────────────────╮
│  System Node 20.20.2 at /usr/bin/node is below the required Node        │
22.14+. Using /home/orin/.nvm/versions/node/v22.22.2/bin/node for the  │
│  daemon. Install Node 24 (recommended) or Node 22 LTS from nodejs.org   │
│  or Homebrew.                                                           │
├─────────────────────────────────────────────────────────────────────────╯
◇  Gateway runtime ──────────────────────────────────────────────────────╮
│  System Node 20.20.2 at /usr/bin/node is below the required Node       │
22.14+. Install Node 24 (recommended) or Node 22 LTS from nodejs.org  │
│  or Homebrew.                                                          │
├────────────────────────────────────────────────────────────────────────╯
◇  Gateway runtime ────────────────────────────────────────────────╮
│  System Node 22 LTS (22.14+) or Node 24 not found. Install via   │
│  Homebrew/apt/choco and rerun doctor to migrate off Bun/version  │
│  managers.                                                       │
├──────────────────────────────────────────────────────────────────╯


Source pointers:

- `src/commands/daemon-install-helpers.ts:524-530` — first emit site (`emitDaemonInstallRuntimeWarning`, title `"Gateway runtime"`).
- `src/commands/doctor-gateway-services.ts:425-434` — second + third emit sites (`renderSystemNodeWarning(systemNodeInfo)` then an unconditional `note("System Node 22 LTS ... not found ...", "Gateway runtime")`).
- `src/daemon/runtime-paths.ts:181-191``renderSystemNodeWarning(systemNode, selectedNodePath?)`. The "Using `<path>` for the daemon" sentence is gated on `selectedNodePath`; the doctor-side call site does not pass it, which is why Panels 1 and 2 differ only by that sentence.

`openclaw status` confirms the very same daemon is up and using the same nvm Node 22 (Slack channel `OK`, sessions running on `claude-opus-4-7`). So the third panel's "not found" is provably incorrect at the same instant.

Impact and severity

  • Affected: any user whose system Node is below 22.14+ and who has a working Node 22+ from nvm / asdf / fnm / volta (i.e. the typical Linux/dev-machine configuration). Reproduced on Ubuntu 24.04 + nvm; the same code paths run on macOS/Windows.
  • Severity: Low–Medium. Annoying / confusing UX, not blocking. Common-user-visible because every doctor run shows it.
  • Frequency: Always, on every openclaw doctor invocation in the affected layout.
  • Consequence: Users following the third panel's advice ("Install Node 22 LTS via Homebrew/apt/choco") may wipe or shadow a working nvm Node 22 chain that doctor itself just reported as "Using … for the daemon." At minimum it costs time chasing a non-issue and undermines trust in the doctor output.

Additional information

  • Repro is on current origin/main (e28ad6a869), so the bug is present on the branch that will produce the next release.
  • Closest existing issue: #60612 ("Doctor warns about NVM node instead of Homebrew/system node, but cannot be fixed") — different angle. #60612 is asking how to suppress the warning on macOS Homebrew; it does not describe three panels under the same heading or the contradictory "not found" text. No existing open or recently-closed issue (searched doctor "Gateway runtime", doctor three panels, doctor "Node 22 LTS" "not found", doctor duplicate panel node, doctor contradictory node, doctor repeats) matches this defect.
  • Suggested fix sketch (for context, not for triage decisions): consolidate the two doctor-side notes into a single panel that defers to renderSystemNodeWarning(systemNodeInfo, selectedNodePath) exactly once, gate the "not found" message on !selectedNodePath (i.e. only fire when no Node 22+ was discovered anywhere — system or version-managed), and let daemon-install-helpers.ts:524 skip emitting if the doctor pass already emitted in the same run.

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…

FAQ

Expected behavior

A single Gateway runtime panel that explains the situation once: system Node is below the minimum, OpenClaw is falling back to the version-manager Node it actually uses, and what the user can do about it. No panel should claim Node 22 LTS is "not found" when a supported Node 22 binary was discovered and is being used by the daemon.

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 [Bug]: `openclaw doctor` emits 3 redundant "Gateway runtime" panels and the third one falsely says "Node 22 LTS or Node 24 not found" when nvm Node 22 is found and in use [2 pull requests, 2 comments, 2 participants]