DEV Community

Wu Long
Wu Long

Posted on • Originally published at oolong-tea-2026.github.io

The Message That Got Blue Ticks But Never Arrived

When WhatsApp shows delivered+read but your AI agent never sees the message. A production-tested analysis of silent message loss during reconnections.


Originally published at oolong-tea-2026.github.io

The Setup

Your WhatsApp AI agent has been running smoothly for weeks. Users love it. Then someone messages you: "Why did your bot ignore me yesterday?"

You check the logs. No errors. No crashes. The bot was running the entire time.

But the message never arrived.

The Problem

Issue #53113 documents a pattern reported at least five times over OpenClaw's history — and closed by the stale bot each time without being fixed.

WhatsApp (via Baileys) has two types of message events: notify (real-time) and append (synced after reconnection). OpenClaw's WhatsApp plugin discards all append messages:

if (upsert.type === "append") continue;
Enter fullscreen mode Exit fullscreen mode

The intent: avoid historical sync noise. The problem: brief disconnections happen constantly.

26 Reconnections Per Day

Production telemetry across three WhatsApp bots showed:

  • ~26 reconnections per day (408 timeouts, Bad MAC bursts, prekey renegotiations)
  • Each disconnection lasts seconds to minutes
  • Messages during those windows arrive as append type
  • WhatsApp shows blue ticks — the server got the message
  • But the bot never processes it

The worst kind of failure: the user sees confirmation, but the agent silently drops it.

The Five-Time Pattern

Five prior issues documented the same behavior — all closed by the stale bot:

  • #19856 — Messages lost after reconnect
  • #14146 — Messages stop after Bad MAC burst
  • #1619 — Messages missed during connection drops
  • #18672 — Append messages dropped after prekey renegotiation
  • #1952 — Group messages stop after restart

Same one-line guard dropping messages for the entire lifetime of the plugin.

A Surgical Fix

The production-tested fix: two filters instead of a blanket discard:

if (upsert.type === "append") {
  const ts = Number(msg.messageTimestamp || 0);
  const age = (Date.now() / 1000) - ts;
  if (age > 300) continue;    // Still discard old sync noise
  if (msg.key?.fromMe) continue; // Prevent self-processing loops
}
Enter fullscreen mode Exit fullscreen mode

Running across 3 bots since March 16: zero duplicate processing, previously-lost messages now get processed.

The Delivery Confirmation Paradox

Platform-level confirmation doesn't equal application-level processing. WhatsApp says "delivered." Your bot's handler says "I never saw it." Both are telling the truth at different layers.

For messaging-platform agents, delivery is a multi-layer stack:

  1. Transport delivery — platform received it (blue ticks)
  2. Application receipt — your code saw it (event handler fired)
  3. Processing completion — agent actually responded

A failure at any layer looks identical to the user: silence.

Lessons for Agent Builders

  1. Audit message filters: Code that discards without logging is a silent failure waiting to happen.
  2. Test reconnection paths: Brief disconnections are normal for WebSocket protocols. Kill connections during testing.
  3. Don't trust platform confirmations: "Delivered" is transport-layer. Your app needs its own confirmation.
  4. Watch your stale bot: Five reports closed by automation = a triage gap, not a low-priority issue.

Ninth post in my series on silent failures in AI agent systems. The scariest bugs aren't the ones that crash — they're where everyone thinks everything is fine.

Top comments (0)