fix(whatsapp): route opening-phase Baileys 428 through reconnect policy and lock in post-open retry#75773
Conversation
|
Codex review: needs changes before merge. Summary Reproducibility: yes. for the opening-phase path: source inspection on current main shows non-auth setup errors from openConnection are rethrown, and #75736 includes live Boom 428 channel-exited logs. The full Windows event-loop-stall root cause in #77443 was not reproduced here. Real behavior proof Next step before merge Security Review findings
Review detailsBest possible solution: Merge the runtime and regression-test changes after the changelog says this fixes #75736 and only references the retry-path mitigation for #77443. Do we have a high-confidence way to reproduce the issue? Yes for the opening-phase path: source inspection on current main shows non-auth setup errors from openConnection are rethrown, and #75736 includes live Boom 428 channel-exited logs. The full Windows event-loop-stall root cause in #77443 was not reproduced here. Is this the best way to solve the issue? No as submitted. The runtime change is the narrow WhatsApp-owned fix for setup 428 handling, but the changelog must not claim the separate Windows stall root cause is fixed. Full review comments:
Overall correctness: patch is incorrect Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 5df08201ff50. |
10552b2 to
7fc1560
Compare
88dcfbf to
89ea1ab
Compare
|
Hi, @steipete |
8431b05 to
cc8355c
Compare
|
@clawsweeper The revised commit addresses both P2 findings:
|
67cd551 to
9977cf4
Compare
|
Hi, @obviyus |
7183d34 to
f1ed4ca
Compare
|
Live validation on PR head Checks run:
Results:
Live smoke: Started gateway with a linked WhatsApp account and sent an inbound message. Confirmed:
|
Before fix — behavior proof (opening-phase 428, issue #75736)
After fix — behavior proof (opening-phase 428)Routes through reconnect policy with diagnostics: After fix — behavior proof (post-open 428, issue #77443)Post-open Baileys 428 (Windows event-loop stall) retries instead of dying: Test coverage |
4168d41 to
a187437
Compare
Co-authored-by: dataCenter430 <[email protected]>
Co-authored-by: dataCenter430 <[email protected]>
|
Landed via rebase merge onto Proof:
Source commits: Landed commits: Thanks @dataCenter430. |
…on on disconnect + 428 reconnect handling - Add z-ai-web-dev-sdk as Strategy 0 (primary) for bot AI responses - works without any API key configuration - Add OpenAI-compatible provider from DB as Strategy 2 (between Gemini REST and local API) - Reorder strategies: z-ai-sdk → Gemini REST → OpenAI provider → Local API → fallback - Fix QR code regeneration: disconnect now properly clears auth + resets serviceInitialized flag so next connect() creates fresh socket and QR - Handle Baileys 428 (connectionClosed) as retryable per openclaw/openclaw#75773 - only 440 (session conflict) is non-retryable - Add isNonRetryableDisconnect() helper following PR #75773 pattern - Add detailed logging for each AI strategy attempt and failure - Frontend: add disconnected state tracking, Reconnect button, proper status reset after disconnect - Fix jidEncode type to use 'any' for server param (Baileys uses JidServer type) - Install z-ai-web-dev-sdk dependency
Summary
DisconnectReason.connectionClosed(428) thrown during the opening phase (openConnection) escaped the WhatsApp reconnect loop and surfaced in the generic channel manager as a barechannel exitederror — no retry, no WhatsApp-specific guidance, no relink prompt.DefaultResourceLoader.reload()blocks the Node.js event loop with synchronous file I/O during first agent startup (eventLoopDelayMaxMs=12088ms). While blocked, Baileys keepalive timers cannot fire, causing a post-open 428 close. Without a correct retry path the channel dies permanently and all subsequent model calls stall.monitor.tscatch block): 428 thrown fromopenConnectionis now caught and routed throughconsumeReconnectAttempt()— retries with backoff up tomaxAttempts, then stops with a clear diagnostic and relink prompt instead of escaping to the generic channel manager.isNonRetryableWebCloseStatus): 428 is explicitly kept retryable (only 440 is non-retryable). Added a comment documenting the Windows event-loop-stall scenario so future PRs cannot reintroduce a non-retryable 428 path that would make [Bug]: WhatsApp event loop blocked (eventLoopDelayMaxMs=12088ms) on first inbound message — 2026.5.3-1 Windows #77443 worse.connection-and-logging.e2e.test.ts): two new tests locking in opening-phase 428 retry ([Bug]: gateway/channels/whatsapp — channel exited with HTTP 428 Precondition Required #75736) and post-open 428 retry ([Bug]: WhatsApp event loop blocked (eventLoopDelayMaxMs=12088ms) on first inbound message — 2026.5.3-1 Windows #77443).DefaultResourceLoader.reload()0.71.1) requires a separate investigation with live Windows reproduction.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
catchblock in the opening phase ofmonitorWebChannelonly handledWhatsAppAuthUnstableError; Boom 428 fromwaitForWaConnectionwas re-thrown to the generic channel manager.DefaultResourceLoader.reload()(v0.71.1, bumped in040f533f60) uses synchronousreaddirSync/readFileSync/statSynccalls that block the main event loop on Windows for 10+ seconds on first agent startup. Baileys firesDisconnectReason.connectionClosed(428) when its keepalive timers cannot fire during the stall. Post-open 428 was already retryable but this PR adds explicit test coverage and commentary to prevent regression.Regression Test Plan (if applicable)
extensions/whatsapp/src/auto-reply.web-auto-reply.connection-and-logging.e2e.test.tsopenConnectionthrows Boom 428 → monitor retries through reconnect policy, emits "Retry N/M", stops with "N/N attempts" on exhaustion — not achannel exitedrethrow. (Covers [Bug]: gateway/channels/whatsapp — channel exited with HTTP 428 Precondition Required #75736)User-visible / Behavior Changes
channel exited, the WhatsApp reconnect loop retries with backoff and gives a clear relink prompt on exhaustion.Diagram (if applicable)
Security Impact (required)
Repro + Verification
Environment
Steps
openConnection(opening-phase)Expected
Actual (before fix)
channel exitedwith no guidanceReal behavior proof
channel exitedwith no retry or guidance. Post-open 428 (Windows event-loop stall) caused the channel to die permanently.defaultchannel, loopback Gateway.openclaw gateway --dev --bind loopback[whatsapp] Listening for personal WhatsApp inbound messages.channel exited,web reconnect, andListeninglines.Redacted runtime log from the live gateway run:
channel exitedline appeared. Status 440 (session conflict) still stops immediately — unchanged.Evidence
Human Verification (required)
oxfmt --checkclean, live gateway run confirming retry behavior on 428.Review Conversations
Compatibility / Migration
Risks and Mitigations
maxAttempts) and stops with a relink prompt.