Skip to content

fix(whatsapp): keep pre-connect recovery replayable#104450

Merged
steipete merged 1 commit into
mainfrom
codex/fix-whatsapp-startup-recovery
Jul 11, 2026
Merged

fix(whatsapp): keep pre-connect recovery replayable#104450
steipete merged 1 commit into
mainfrom
codex/fix-whatsapp-startup-recovery

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Fixes #91212

AI-assisted implementation; maintainer-reviewed and source-verified.

What Problem This Solves

Fixes a startup recovery path where WhatsApp could classify a missing outbound listener as an attempted send. Durable recovery then preserved false send evidence instead of safely retrying after the listener connected.

Why This Change Was Made

The WhatsApp adapter now uses the existing public SDK PlatformMessageNotDispatchedError for its pre-send listener gate. That lets the shared durable recovery path clear false attempt evidence while keeping the pending intent for the existing reconnect drain.

The fix stays at the transport owner boundary and reuses the generic durable marker instead of adding delay heuristics or a WhatsApp-specific retry queue.

User Impact

Messages queued before the WhatsApp listener is ready can recover after connect without being lost or sent twice.

Evidence

  • Real-adapter regression: enqueue before listener, pre-connect drain fails safely, listener connects, two subsequent drains produce exactly one recipient send.
  • Blacksmith Testbox pearl-hermit (tbx_01kx8fss8mm2ef6888c3qjen9f) focused proof: 36 tests passed.
  • Testbox check:changed passed.
  • Full Testbox build passed.
  • Structured Codex autoreview: clean; no accepted or actionable findings.
  • Remaining live proof gap: no credentialed WhatsApp restart roundtrip was run.

@openclaw-barnacle openclaw-barnacle Bot added channel: whatsapp-web Channel integration: whatsapp-web size: S maintainer Maintainer-authored PR labels Jul 11, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels Jul 11, 2026
@clawsweeper

clawsweeper Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 11, 2026, 8:02 AM ET / 12:02 UTC.

Summary
The PR wraps WhatsApp’s missing active-listener failure in PlatformMessageNotDispatchedError and adds an adapter-plus-durable-queue regression proving one replayed send after listener registration.

PR surface: Source +2, Tests +119. Total +121 across 3 files.

Reproducibility: yes. for the WhatsApp subproblem from source with high confidence: the active-listener gate occurs before every platform send, while current main throws an unmarked generic error that durable recovery cannot safely classify as unsent. No credentialed current-main restart was run.

Review metrics: none identified.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #91212
Summary: This PR is a partial WhatsApp-specific fix candidate for the canonical cross-channel startup recovery issue.

Members:

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

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • Post redacted credentialed WhatsApp restart evidence showing one queued message delivered exactly once after reconnect.
  • [P1] Replace the closing reference to the broader issue with a non-closing partial-fix link.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR provides a real-adapter/shared-queue regression and Testbox validation but explicitly lacks a credentialed WhatsApp restart roundtrip; add redacted live output, logs, or a recording, then update the PR body to trigger a fresh review or ask a maintainer to comment @clawsweeper re-review.

Risk before merge

  • [P1] The PR body currently uses a closing reference for [Bug]: delivery-recovery 0 recovered / N failed after gateway restart — recovery starts before channel transport ready #91212, but that issue still tracks distinct Feishu readiness and shared recovery work outside this WhatsApp-only diff.
  • [P1] The reported regression uses a mocked active listener and no credentialed WhatsApp restart roundtrip, so real connection timing and exactly-once delivery remain unobserved.
  • [P1] The changed classification directly controls durable replay; a mistaken boundary could cause message loss or duplication even when unit and integration checks pass.

Maintainer options:

  1. Narrow linkage and prove live behavior (recommended)
    Replace the broad issue-closing reference with a partial-fix link and attach redacted credentialed WhatsApp restart evidence before merge.
  2. Accept adapter-level proof
    Merge the scoped code while explicitly ensuring the broader issue remains open and accepting that real reconnect timing was not exercised.

Next step before merge

  • [P1] The code has no discrete repair finding; a human should enforce the protected maintainer review, real-behavior proof gate, and non-closing linkage to the broader issue.

Security
Cleared: The patch changes only runtime error classification and tests, with no dependency, workflow, permission, secret, downloaded-code, package-resolution, or publishing changes.

Review details

Best possible solution:

Keep the transport-owned marker change and regression, replace the broad closing reference with a non-closing partial-fix link, and add redacted credentialed WhatsApp restart evidence showing the queued message is delivered exactly once after the real listener connects.

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

Yes for the WhatsApp subproblem from source with high confidence: the active-listener gate occurs before every platform send, while current main throws an unmarked generic error that durable recovery cannot safely classify as unsent. No credentialed current-main restart was run.

Is this the best way to solve the issue?

Yes for the WhatsApp behavior: using the existing public pre-dispatch marker at the transport-owned listener gate is narrower and safer than adding delay heuristics or a parallel retry queue. It is not a complete resolution of the linked cross-channel issue.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 90e465833b30.

Label changes

Label changes:

  • add P1: The PR addresses a restart recovery path that can suppress queued WhatsApp messages for real users.
  • add merge-risk: 🚨 message-delivery: The changed pre-dispatch classification determines whether durable recovery retries, loses, or duplicates a queued message.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR provides a real-adapter/shared-queue regression and Testbox validation but explicitly lacks a credentialed WhatsApp restart roundtrip; add redacted live output, logs, or a recording, then update the PR body to trigger a fresh review or ask a maintainer to comment @clawsweeper re-review.

Label justifications:

  • P1: The PR addresses a restart recovery path that can suppress queued WhatsApp messages for real users.
  • merge-risk: 🚨 message-delivery: The changed pre-dispatch classification determines whether durable recovery retries, loses, or duplicates a queued message.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR provides a real-adapter/shared-queue regression and Testbox validation but explicitly lacks a credentialed WhatsApp restart roundtrip; add redacted live output, logs, or a recording, then update the PR body to trigger a fresh review or ask a maintainer to comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +2, Tests +119. Total +121 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 1 3 1 +2
Tests 2 140 21 +119
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 143 22 +121

What I checked:

Likely related people:

  • steipete: Peter is assigned to the canonical issue and is credited in recent merged pre-connect recovery, durable outbound, and WhatsApp reconnect work beyond authoring this proposal. (role: recent recovery-path contributor and issue assignee; confidence: high; commits: 13f8dfae864f, 741d9524bec2, 4c42815348ae; files: src/infra/delivery-recovery.shared.ts, src/infra/outbound/delivery-queue-recovery.ts, extensions/whatsapp/src/auto-reply/monitor.ts)
  • SunnyShu0925: Authored the merged change that added retry handling for proven pre-connect failures in the shared durable recovery path. (role: introduced shared pre-connect recovery behavior; confidence: high; commits: 13f8dfae864f; files: src/infra/delivery-recovery.shared.ts, src/infra/outbound/delivery-queue-recovery.ts)
  • zhangguiping-xydt: Authored recent merged work preserving outbound recovery send evidence across adapters, directly adjacent to the invariant this PR relies on. (role: recent durable outbound contributor; confidence: high; commits: 741d9524bec2, babc287afe56; files: extensions/whatsapp/src/send.ts, src/infra/delivery-recovery.shared.ts, src/infra/outbound/delivery-queue-recovery.ts)
  • VishalJ99: Authored the recent WhatsApp reconnect catch-up change in the monitor path that owns the drain used by this fix. (role: recent WhatsApp reconnect contributor; confidence: high; commits: 4c42815348ae; files: extensions/whatsapp/src/auto-reply/monitor.ts)
  • mcaxtr: Recent merged WhatsApp connection, auth, socket, and send-path work makes Marcus a useful adjacent reviewer for live reconnect behavior. (role: recent WhatsApp connection-area contributor; confidence: medium; commits: 6ba19c5ad019, 52d9d16e1be9, 7d8b000bf78a; files: extensions/whatsapp/src/send.ts, extensions/whatsapp/src/auto-reply/monitor.ts, extensions/whatsapp/src/connection-controller.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.

@steipete

Copy link
Copy Markdown
Contributor Author

Land-ready verification complete for exact head c80db1dbcdfcdeeba6b38733d71f4597f95683e5.

  • Blacksmith Testbox pearl-hermit (tbx_01kx8fss8mm2ef6888c3qjen9f): focused WhatsApp proof, 36 tests passed.
  • Same Testbox: check:changed passed; full pnpm build passed.
  • GitHub CI run 29151758614: success on the exact PR head.
  • Fresh structured Codex autoreview: clean, no accepted/actionable findings.
  • Repository review artifacts: validated with zero findings; OPENCLAW_TESTBOX=1 scripts/pr prepare-run 104450 passed.

Behavior proof: enqueue before the listener exists, retain the pending intent through a pre-connect drain, connect the listener, and drain twice; exactly one platform send occurs.

Known gap: no credentialed WhatsApp restart roundtrip was run. The changed transport gate and SQLite-backed real-adapter recovery path are covered directly.

@steipete
steipete merged commit 1285fd6 into main Jul 11, 2026
143 of 149 checks passed
@steipete
steipete deleted the codex/fix-whatsapp-startup-recovery branch July 11, 2026 12:04
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

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 maintainer Maintainer-authored PR merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: delivery-recovery 0 recovered / N failed after gateway restart — recovery starts before channel transport ready

1 participant