Skip to content

fix(gateway): distinguish reachable gateway from failed status probe#98183

Merged
vincentkoc merged 2 commits into
openclaw:mainfrom
masatohoshino:fix/gateway-status-reachable-probe-failed
Jul 2, 2026
Merged

fix(gateway): distinguish reachable gateway from failed status probe#98183
vincentkoc merged 2 commits into
openclaw:mainfrom
masatohoshino:fix/gateway-status-reachable-probe-failed

Conversation

@masatohoshino

Copy link
Copy Markdown
Contributor

What Problem This Solves

openclaw gateway status prints Warm-up: launch agents can take a few seconds. Try again shortly. whenever the RPC probe fails while the managed service is loaded and running — even when the gateway process is up and owns its port and the probe is failing for an unrelated reason such as a wrong probe auth token or bad config.

In that state the gateway is clearly not "warming up", so telling the operator to wait and retry is the wrong nudge — they should be checking the probe credentials/config (or restarting if the gateway is wedged). This follows the same status-distinction lineage as the recent /status slices (#97479, #97878).

Why This Change Was Made

Deep status already computes status.health.healthy, which is running && owns-the-listening-port (it is not a reachability proof). When that is true and the RPC probe still fails, it is an unambiguous "not warm-up" signal, so the message changes from warm-up to recovery guidance. Everything else keeps the existing warm-up message:

  • health.healthy === true: the gateway process is running and owns the port, so a failed probe is not a warm-up delay. The cause is probe credentials/config or a wedged gateway (a wedged gateway that still owns the port is also reported as healthy === true), so we point the operator at both paths without asserting a single cause.
  • otherwise: keep the existing warm-up message. health.healthy === false is deliberately not redirected — it is ambiguous (a just-started gateway reports false until it binds the port; the port may be held by a foreign process; or a stale gateway PID may own it), and those cases are already covered by the dedicated stale-PID, "port not listening", and port-conflict diagnostics elsewhere in the status output. Unknown health (shallow status) also keeps warm-up.

This is presentation-only. Health computation, probe behavior, service-manager behavior, config, and RPC are untouched; no new config/default surfaces, no new imports.

User Impact

When the RPC probe fails on a running service whose gateway owns the port, openclaw gateway status now prints:

Gateway process is running and owns the gateway port, so this is not a warm-up delay. Check the probe credentials/config, or restart the gateway and inspect its logs if it stays unresponsive.

instead of the generic warm-up line. All other states (gateway still starting up, port held by another process, stale PID, or unknown health) keep the existing warm-up message and the existing dedicated diagnostics. No behavior change beyond the printed guidance text.

Evidence

  • Focused render tests — pnpm test src/cli/daemon-cli/status.print.test.ts → 20 passed (17 existing + 3 new):
    • health.healthy:true + failed probe + running → owns-port "not a warm-up delay" guidance, no warm-up line.
    • health.healthy:false + port busy + running → warm-up line preserved, no "Gateway process is …" guidance (guards against misfiring restart guidance on a foreign port conflict).
    • no health → existing warm-up line preserved, no "Gateway process is …" line.
  • Typecheck: pnpm tsgo:core and pnpm tsgo:test:src clean. Format: oxfmt --check clean.
  • Render-path capture — invoked the real printDaemonStatus (no mocks; real CLI status styles, real formatCliCommand, real runtime) with a constructed DaemonStatus per case. This exercises the changed render path, not gather/deep status (which is unchanged). Excerpted output (surrounding status lines omitted):
########## health.healthy=true + port busy (running, owns port, probe failed) ##########
Runtime: running (pid 8000)
Gateway process is running and owns the gateway port, so this is not a warm-up delay. Check the probe credentials/config, or restart the gateway and inspect its logs if it stays unresponsive.
Connectivity probe: failed
  gateway closed (1008 policy violation: invalid token)

########## health.healthy=false + port busy (unhealthy/ambiguous) ##########
Runtime: running (pid 8000)
Warm-up: launch agents can take a few seconds. Try again shortly.

########## health=undefined + port busy (shallow status, unknown) ##########
Runtime: running (pid 8000)
Warm-up: launch agents can take a few seconds. Try again shortly.

@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: S labels Jun 30, 2026
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 1, 2026, 7:59 PM ET / 23:59 UTC.

Summary
The PR changes openclaw gateway status rendering and focused tests so a failed RPC probe on a running gateway with healthy/no-stale health shows recovery guidance instead of the warm-up hint.

PR surface: Source +21, Tests +158. Total +179 across 2 files.

Reproducibility: yes. by source inspection: current main unconditionally prints the warm-up hint for a failed RPC probe while the loaded service runtime is running. The stale-PID edge case is also source-reproducible because restart health can be healthy while stale gateway PIDs remain non-empty.

Review metrics: none identified.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • No automated repair lane is needed; the remaining work is ordinary maintainer review, CI completion, and merge gating for a focused PR with no findings.

Security
Cleared: The diff only changes CLI status text and colocated tests; it adds no dependency, workflow, secret, auth, network, or package execution surface.

Review details

Best possible solution:

Land the renderer-only diagnostic change after ordinary maintainer review and CI, keeping health computation, RPC probing, service management, config, and defaults unchanged.

Do we have a high-confidence way to reproduce the issue?

Yes by source inspection: current main unconditionally prints the warm-up hint for a failed RPC probe while the loaded service runtime is running. The stale-PID edge case is also source-reproducible because restart health can be healthy while stale gateway PIDs remain non-empty.

Is this the best way to solve the issue?

Yes. The renderer is the narrow owner for this operator-facing wording, and the PR uses existing restart-health fields while preserving warm-up behavior for stale, unhealthy, and unknown health states.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 3e50f41dd6ea.

Label changes

Label justifications:

  • P2: This is a normal-priority gateway CLI diagnostic bug fix with limited blast radius and no config, auth, persistence, or runtime behavior change.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes copied terminal output from the real printDaemonStatus render path showing the after-fix guidance and preserved warm-up cases.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied terminal output from the real printDaemonStatus render path showing the after-fix guidance and preserved warm-up cases.
Evidence reviewed

PR surface:

Source +21, Tests +158. Total +179 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 24 3 +21
Tests 1 158 0 +158
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 182 3 +179

What I checked:

  • Current main behavior: printDaemonStatus on current main logs Warm-up: launch agents can take a few seconds. Try again shortly. whenever rpc exists, rpc.ok is false, the service is loaded, and runtime status is running. (src/cli/daemon-cli/status.print.ts:266, 3e50f41dd6ea)
  • PR head condition: The PR gates the new recovery guidance on status.health?.healthy === true plus an empty staleGatewayPids list, preserving the warm-up hint otherwise. (src/cli/daemon-cli/status.print.ts:280, 40d6a6f02099)
  • PR regression coverage: The PR adds render tests for healthy/no-stale guidance, healthy-with-stale warm-up preservation, unhealthy health, and unknown health. (src/cli/daemon-cli/status.print.test.ts:870, 40d6a6f02099)
  • Status gather contract: gatherDaemonStatus calls inspectGatewayRestart when probing is enabled and the RPC probe fails, then carries healthy and staleGatewayPids into the printable DaemonStatus. (src/cli/daemon-cli/status.gather.ts:717, 3e50f41dd6ea)
  • Restart-health semantics: inspectGatewayRestart computes health from running service/listener ownership or attribution-gap reachability and separately returns stale gateway PIDs, which is the sibling contract this renderer now consumes. (src/cli/daemon-cli/restart-health.ts:421, 3e50f41dd6ea)
  • History provenance: Feature history ties the central health fields to gateway restart/status work: 8db6fcca added status health propagation/stale-PID rendering, c3810346 adjusted listener-attribution restart health, and 905e355f introduced restart-health verification. (src/cli/daemon-cli/restart-health.ts:39, c3810346f945)

Likely related people:

  • vincentkoc: Authored the merged listener-attribution restart-health change whose healthy semantics this PR consumes. (role: recent area contributor and merger; confidence: high; commits: c3810346f945; files: src/cli/daemon-cli/restart-health.ts, src/cli/daemon-cli/restart-health.test.ts)
  • sallyom: Authored the merged gateway CLI hardening work that propagated health into daemon status and added stale-PID status rendering. (role: feature owner for status health diagnostics; confidence: high; commits: 8db6fcca777a; files: src/cli/daemon-cli/status.gather.ts, src/cli/daemon-cli/status.print.ts, src/cli/daemon-cli/status.print.test.ts)
  • Peter Steinberger: Git history shows the restart-health module was introduced in the daemon restart health verification commit. (role: original restart-health introducer; confidence: medium; commits: 905e355f651d; files: src/cli/daemon-cli/restart-health.ts, src/cli/daemon-cli/lifecycle.ts)
  • masatohoshino: Authored this PR and recently authored merged status-distinction work cited by the PR as lineage. (role: recent adjacent status contributor; confidence: medium; commits: 949b1af433c6, 888f399499c4; files: src/status/status-plugin-health.ts, src/status/status-plugin-health.runtime.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels Jun 30, 2026
@masatohoshino
masatohoshino force-pushed the fix/gateway-status-reachable-probe-failed branch from 0dec0a7 to 7fbaef0 Compare July 1, 2026 14:00
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 1, 2026
@vincentkoc vincentkoc self-assigned this Jul 1, 2026
… PIDs

inspectGatewayRestart can set health.healthy from bare reachability after
ownership attribution failed, while still returning a non-empty
staleGatewayPids. Printing owns-port recovery guidance in that case
contradicted the dedicated stale-PID diagnostic below it. Require
staleGatewayPids to be empty before treating healthy as owns-port proof.
@vincentkoc
vincentkoc requested a review from a team as a code owner July 1, 2026 23:54
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: telegram Channel integration: telegram channel: tlon Channel integration: tlon channel: whatsapp-web Channel integration: whatsapp-web app: android App: android app: ios App: ios app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime labels Jul 1, 2026
@openclaw-barnacle openclaw-barnacle Bot added size: S and removed docs Improvements or additions to documentation channel: discord Channel integration: discord channel: telegram Channel integration: telegram channel: tlon Channel integration: tlon channel: whatsapp-web Channel integration: whatsapp-web app: android App: android app: ios App: ios app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime scripts Repository scripts commands Command implementations agents Agent runtime and tooling channel: feishu Channel integration: feishu extensions: openai extensions: nvidia channel: qqbot extensions: qa-lab extensions: memory-wiki extensions: codex extensions: inworld Extension: inworld extensions: opencode-go size: XL labels Jul 1, 2026
@vincentkoc
vincentkoc merged commit 8e28e88 into openclaw:main Jul 2, 2026
113 of 116 checks passed
@vincentkoc

Copy link
Copy Markdown
Member

Merged via squash.

vincentkoc added a commit that referenced this pull request Jul 2, 2026
* origin/main:
  test(gateway): isolate live release agent state
  test(plugins): repair prerelease validation fixtures
  fix(discord): guard JSON.parse against malformed API response bodies (#97889)
  fix(codex): preserve app approvals in side forks (#98812)
  fix(agents): don't inject A2A turns into isolated-cron sessions_send (#92257) (#92283)
  fix(browser): guard setDeep against empty keys array (#98138)
  docs(telegram): move maintainer decisions into scoped AGENTS.md
  fix(ios): generate light app store screenshots only
  fix(gateway): distinguish reachable gateway from failed status probe (#98183)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 2, 2026
…penclaw#98183)

* fix(gateway): distinguish reachable gateway from failed status probe

* fix(status): gate owns-port RPC recovery guidance on no stale gateway PIDs

inspectGatewayRestart can set health.healthy from bare reachability after
ownership attribution failed, while still returning a non-empty
staleGatewayPids. Printing owns-port recovery guidance in that case
contradicted the dedicated stale-PID diagnostic below it. Require
staleGatewayPids to be empty before treating healthy as owns-port proof.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants