Skip to content

fix(gateway): stop terminal WhatsApp restart loops#78511

Merged
steipete merged 3 commits into
openclaw:mainfrom
openperf:fix/78419-whatsapp-terminal-disconnect
Jul 5, 2026
Merged

fix(gateway): stop terminal WhatsApp restart loops#78511
steipete merged 3 commits into
openclaw:mainfrom
openperf:fix/78419-whatsapp-terminal-disconnect

Conversation

@openperf

@openperf openperf commented May 6, 2026

Copy link
Copy Markdown
Member

What Problem This Solves

Terminal WhatsApp disconnects such as logged-out and connection-replaced sessions could continue through recovery-stop timeout handling and schedule another automatic restart, creating a restart loop instead of waiting for operator reconnection.

Refs #78419.

Why This Change Was Made

The repaired branch carries the WhatsApp-owned terminal-disconnect fact through the generic channel snapshot and makes gateway restart policy check it before recovery timeout handling. Terminal state clears pending restart bookkeeping and resets attempts; ordinary transient disconnect recovery is unchanged.

User Impact

Logged-out or replaced WhatsApp sessions stop restarting automatically and remain stopped until the account is reconnected, avoiding noisy restart loops and repeated failed work.

Evidence

  • Final-rebase focused proof: 24 unit-fast, 332 gateway, and 12 WhatsApp tests passed.
  • Remote Testbox build and changed gate passed: tbx_01kws0677akakqfpk9p8s1a0f9, Actions run 28739070734.
  • Fresh Codex autoreview: clean, no accepted/actionable findings.
  • Exact prepared head: 7c741fc2bbbc848ccf25374f34268ec002d36496.

@openclaw-barnacle openclaw-barnacle Bot added channel: whatsapp-web Channel integration: whatsapp-web gateway Gateway runtime size: S maintainer Maintainer-authored PR labels May 6, 2026
@openperf
openperf force-pushed the fix/78419-whatsapp-terminal-disconnect branch from 302204d to ecfa1cd Compare May 6, 2026 14:30
@clawsweeper

clawsweeper Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 5, 2026, 8:45 AM ET / 12:45 UTC.

Summary
Adds a WhatsApp-owned terminalDisconnect flag to channel/runtime status snapshots and makes gateway restart policy skip health-monitor and recovery-timeout restarts for terminal WhatsApp disconnects, with focused regression coverage.

PR surface: Source +41, Tests +209, Docs +1. Total +251 across 17 files.

Reproducibility: yes. from source inspection rather than a live run: current main treats any managed stopped channel as not-running, and the health monitor restarts unhealthy accounts. The linked production report supplies the WhatsApp terminal-disconnect path and observed restart-loop symptoms.

Review metrics: 1 noteworthy metric.

  • Public status surface: 1 optional field added. terminalDisconnect crosses the plugin SDK/channel snapshot boundary and controls restart policy, so maintainers should notice the additive API surface before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #78419
Summary: This PR is the active candidate fix for the canonical WhatsApp terminal-disconnect restart-loop bug; the merged auth-preservation PR is related but adjacent.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🌊 off-meta tidepool
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.

Risk before merge

  • [P1] No exact-head live WhatsApp logged-out or connection-replaced run was visible in the PR body; the evidence is source tracing, regression tests, Testbox/CI, and the linked production report.
  • [P1] The linked bug also requested a reauth-required event/status field and bounded restart budget; this PR fixes the central restart loop but does not implement those broader follow-ups.

Maintainer options:

  1. Decide the mitigation before merge
    Land the focused restart-loop fix if exact-head CI remains green, then preserve any desired reauth-event or restart-budget work as a narrower follow-up to the canonical bug.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • No ClawSweeper repair job is needed; this review found no concrete patch defect for automation to fix.

Security
Cleared: The diff does not change CI, dependencies, secrets, auth storage, permissions, or downloaded code paths, and no concrete security or supply-chain concern was found.

Review details

Best possible solution:

Land the focused restart-loop fix if exact-head CI remains green, then preserve any desired reauth-event or restart-budget work as a narrower follow-up to the canonical bug.

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

Yes, from source inspection rather than a live run: current main treats any managed stopped channel as not-running, and the health monitor restarts unhealthy accounts. The linked production report supplies the WhatsApp terminal-disconnect path and observed restart-loop symptoms.

Is this the best way to solve the issue?

Yes for the central restart-loop bug: the PR carries the WhatsApp-owned terminal-disconnect state through existing snapshot seams and checks it at both restart surfaces. Broader operator reauth events or retry-budget policy should remain separate follow-up work if maintainers want them.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 601b80c5f4c1.

Label changes

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The external-contributor proof gate is not applicable because this is a maintainer-labeled MEMBER PR; the body still includes focused tests and Testbox/Actions evidence, but not live WhatsApp terminal-disconnect proof.

Label justifications:

  • P1: The PR addresses a reported real-world WhatsApp gateway restart loop that caused multi-tenant memory growth, latency, and channel availability degradation.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The external-contributor proof gate is not applicable because this is a maintainer-labeled MEMBER PR; the body still includes focused tests and Testbox/Actions evidence, but not live WhatsApp terminal-disconnect proof.
Evidence reviewed

PR surface:

Source +41, Tests +209, Docs +1. Total +251 across 17 files.

View PR surface stats
Area Files Added Removed Net
Source 9 41 0 +41
Tests 7 209 0 +209
Docs 1 1 0 +1
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 17 251 0 +251

What I checked:

  • Current main restart behavior: On current main, a managed account with running: false is evaluated as not-running, and the health monitor later calls startChannel for unhealthy accounts, which explains why terminal WhatsApp stops can currently re-enter restart handling. (src/gateway/channel-health-policy.ts:63, 601b80c5f4c1)
  • WhatsApp terminal source state: The WhatsApp connection controller already maps logged-out closes to healthState: "logged-out" and non-retryable close status to healthState: "conflict"; the PR carries that owner-produced fact into generic restart policy instead of reclassifying Baileys details in gateway code. (extensions/whatsapp/src/connection-controller.ts:630, 601b80c5f4c1)
  • PR diff carries terminal state through restart surfaces: The PR diff adds terminalDisconnect to WhatsApp status, safe channel account projection, ChannelAccountSnapshot, and plugin-sdk status helpers, then checks it in both the health monitor and channel-manager task-exit recovery path. (src/gateway/server-channels.ts:681, 7c741fc2bbbc)
  • Prior ClawSweeper finding appears addressed: The current diff checks terminal disconnect before the timed-out recovery-stop restart branch and clears recovery bookkeeping, restart attempts, restartPending, and reconnectAttempts, addressing the earlier P2 finding about terminal stops being processed after recovery restarts. (src/gateway/server-channels.ts:681, 7c741fc2bbbc)
  • Focused regression coverage: The PR adds coverage for WhatsApp monitor-state terminal flags, health-policy classification, health-monitor no-restart behavior, channel-manager timed-out recovery completion, channels.status, and plugin-sdk status projection. (src/gateway/server-channels.test.ts:490, 7c741fc2bbbc)
  • Live PR state and protected maintainer signal: Live PR metadata shows author association MEMBER, maintainer label, assignee steipete, head 7c741fc2bbbc848ccf25374f34268ec002d36496, and mergeable state unstable; this should stay open for maintainer handling, not cleanup close. (7c741fc2bbbc)

Likely related people:

  • steipete: Live PR timeline shows steipete assigned himself, renamed the PR, and force-pushed the current head; he authored the recovery-prioritization and changelog commits on this branch. (role: recent branch maintainer; confidence: high; commits: 5a48b0f87588, 7c741fc2bbbc; files: src/gateway/server-channels.ts, src/gateway/server-channels.test.ts, CHANGELOG.md)
  • mcaxtr: mcaxtr authored and merged the related terminal-disconnect auth preservation PR, which overlaps the same WhatsApp logged-out/conflict behavior family. (role: adjacent WhatsApp terminal-disconnect owner; confidence: medium; commits: 52d9d16e1be9, cb6e47241197, 2d3f6c20be62; files: extensions/whatsapp/src/auto-reply/monitor.ts, extensions/whatsapp/src/connection-controller.ts, src/gateway/server-methods/web.ts)
  • Vincent Koc: Current checkout blame for the gateway recovery branch, health policy, and WhatsApp monitor-state code points to commit 53bd4dd; the local history is compact, so this is a weak routing signal. (role: current checkout area contributor; confidence: low; commits: 53bd4dde6c00; files: src/gateway/server-channels.ts, src/gateway/channel-health-policy.ts, extensions/whatsapp/src/auto-reply/monitor-state.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.
Review history (1 earlier review cycle)
  • reviewed 2026-07-03T21:00:19.557Z sha fcd72af :: found issues before merge. :: [P2] Check terminal stops before recovery restarts

@openperf
openperf force-pushed the fix/78419-whatsapp-terminal-disconnect branch 2 times, most recently from 4508ca3 to e0bb6da Compare May 7, 2026 01:25
@clawsweeper clawsweeper Bot added 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. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 14, 2026
@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. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. 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 Jun 15, 2026
@openperf
openperf force-pushed the fix/78419-whatsapp-terminal-disconnect branch from e0bb6da to a322132 Compare June 21, 2026 07:59
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. 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: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. labels Jun 21, 2026
@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. 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. labels Jun 28, 2026
@steipete steipete self-assigned this Jul 5, 2026
@steipete
steipete force-pushed the fix/78419-whatsapp-terminal-disconnect branch from fcd72af to cdf751e Compare July 5, 2026 12:02
@steipete steipete changed the title fix(gateway): skip health-monitor restart for terminal WhatsApp disconnects fix(gateway): stop terminal WhatsApp restart loops Jul 5, 2026
@steipete
steipete force-pushed the fix/78419-whatsapp-terminal-disconnect branch from 67f8fe1 to e9f754f Compare July 5, 2026 12:23
openperf and others added 3 commits July 5, 2026 13:38
Track `terminalDisconnect` through the WhatsApp status controller, channel
runtime snapshot, and `ChannelAccountSnapshot` so the health-monitor and
the `ChannelManager` task-exit handler both skip auto-restart when Baileys
signals a terminal session end (loggedOut / connectionReplaced).

Adds a `terminal-disconnect` `ChannelHealthEvaluationReason` so the policy
layer returns a stable, named reason rather than falling through to
`not-running`, preventing unbounded WebSocket/heap growth on multi-tenant
gateways. Fixes openclaw#78419.
@steipete
steipete force-pushed the fix/78419-whatsapp-terminal-disconnect branch from e9f754f to 7c741fc Compare July 5, 2026 12:38
@clawsweeper clawsweeper Bot added 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: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 5, 2026
@steipete

steipete commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Land-ready proof for exact head 7c741fc2bbbc848ccf25374f34268ec002d36496:

The terminal-disconnect fact remains WhatsApp-owned; core restart policy consumes only the generic channel snapshot and clears pending restart state before recovery timeout handling.

@steipete
steipete merged commit e29448d into openclaw:main Jul 5, 2026
123 of 129 checks passed
@steipete

steipete commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 6, 2026
* fix(gateway): prevent restart loops after terminal WhatsApp disconnects

Track `terminalDisconnect` through the WhatsApp status controller, channel
runtime snapshot, and `ChannelAccountSnapshot` so the health-monitor and
the `ChannelManager` task-exit handler both skip auto-restart when Baileys
signals a terminal session end (loggedOut / connectionReplaced).

Adds a `terminal-disconnect` `ChannelHealthEvaluationReason` so the policy
layer returns a stable, named reason rather than falling through to
`not-running`, preventing unbounded WebSocket/heap growth on multi-tenant
gateways. Fixes openclaw#78419.

* fix(gateway): prioritize terminal disconnect recovery

Co-authored-by: openperf <[email protected]>

* docs(changelog): move WhatsApp restart fix to unreleased

---------

Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: whatsapp-web Channel integration: whatsapp-web gateway Gateway runtime maintainer Maintainer-authored PR P1 High-priority user-facing bug, regression, or broken workflow. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M 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