Skip to content

[BUG] Bot sends to a LID group are permanently stuck at "Waiting for this message" for some devices — sender-key-memory is never invalidated (baileys 7.0.0-rc.9) #2706

Description

@andreaugustobell

Welcome!

  • Yes, I have searched for similar issues on GitHub and found none.

What did you do?

We use Evolution API to post automated alerts into a WhatsApp group, via POST /message/sendText/{instance} addressed to the group JID. The group is fully LID-addressed: ~14 participants, all @lid.

Self-hosted v2.3.7 on systemd (not Docker), Debian 12, Node v20.20.2, Postgres 15, Redis-backed Baileys auth state.

What did you expect?

Every member of the group receives the message and can read it — the same way everyone reads messages posted by a human in that same group.

What did you observe instead of what you expected?

The API accepts every send (HTTP 200, nothing in the logs), but a subset of members never sees the content — only "Waiting for this message. This may take a while.", indefinitely, for more than a week. In the same group:

  • Android members read everything normally;
  • iPhone members read nothing the bot sends;
  • messages posted by humans in that group are read by everyone, including the affected iPhones.

So it is not the group, not the message body, not the pairing.

What we measured. The Baileys state key sender-key-memory-<group>@g.us — a jid → bool map of "who I already sent this group's SenderKey to" — is always 100% true: 29, 22, 30 and 22 device entries on four separate occasions, always zero false. It never self-clears.

Deleting that single field restores delivery, confirmed on the affected users' handsets, 3 out of 3 times (2026-08-03, 2026-08-08, 2026-08-19), and it breaks again within days — 4 events in 21 days. After the deletion the map is rebuilt with fewer entries than the frozen one (30 → 21), so part of the frozen map was dead bookkeeping.

One extra data point that pins the mechanism: an affected iPhone user created a new WhatsApp Business registration and immediately started receiving the bot's group messages, with no change on our side. A fresh registration is a device not yet marked in that map, so it receives the SenderKeyDistributionMessage on the next send; devices already marked true never do.

Screenshots/Videos

No response

Which version of the API are you using?

2.3.7

What is your environment?

Linux

Other environment specifications

Debian GNU/Linux 12 (bookworm), Node v20.20.2, systemd service (not Docker)
baileys 7.0.0-rc.9 — the pin in this repository's package.json (same on main and on the 2.4.0-rc2 tag)
Postgres 15; Redis for Baileys auth state and cache
CACHE_REDIS_ENABLED=true, CACHE_LOCAL_ENABLED=false, CACHE_REDIS_TTL=604800
Target group fully LID-addressed: the 22 device JIDs in its sender-key-memory are all @lid, zero @s.whatsapp.net

If applicable, paste the log output

The application log is clean — that is part of the problem. What follows is state measured directly, with identifiers redacted.

# the group's sender-key bookkeeping map, measured on four occasions
2026-08-03   29 devices, 29 true, 0 false
2026-08-08   22 devices, 22 true, 0 false
2026-08-19   30 devices, 30 true, 0 false
2026-08-24   22 devices, 22 true, 0 false    <- before clearing

# after deleting that one field: no key material touched, session intact
group sender-key-memory maps : 0
sender-key-* (material)      : 2
session-*                    : 141
pre-key-*                    : 1686
Instance.connectionStatus    : open

# getMessage() in the running 2.3.7 bundle (dist/main.js) -- see #2705
async getMessage(e,t=!1){try{ ...$queryRaw`SELECT * FROM "Message" WHERE "instanceId"=... AND "key"->>'id'=${e.id}`;
  if(t)return o[0]; ... return o[0].message }catch{ return {conversation:""} }}

# Message.status for GROUP sends, last 24h
PENDING | 155        (1-1 @lid progresses normally to SERVER_ACK / DELIVERY_ACK / READ)

Additional Notes

Root cause is upstream in baileys — but it reaches users through this project's pin

In baileys@7.0.0-rc.9 and in current master — identical on this point — src/Socket/messages-send.ts reads that map and only ever writes true into it; the comment // on participant change in group, we should do sender memory manipulation is still unimplemented. The only invalidation in the whole library is in sendMessagesAgain (src/Socket/messages-recv.ts):

if (isJidGroup(remoteJid)) {
  await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } })
}

So for groups the retry receipt is not one recovery path among several — it is the only one.

Upstream this is WhiskeySockets/Baileys#2704 (same three root causes: map never invalidated; identity-change notification discarded when the socket was offline; server-side participant-hash correction commented out). It was closed by the stale bot with no maintainer reply. The PRs that fix it — WhiskeySockets/Baileys#2711 and #2748 — have been open and stale since July. WhiskeySockets/Baileys#2297 is the same symptom reported specifically for iOS recipients, open since January.

And #2705 in this repository makes it permanent

getMessage() returns { conversation: '' } on any exception — a truthy object — so Baileys relays an empty envelope and consumes one of the recipient's limited retries. On a miss the query returns [], so rows[0].message?.… throws and lands in the same catch: "not found" and "database error" converge on the same empty envelope, silently. Since the retry receipt is the only thing that can clear sender-key-memory for a group, burning the retries turns a transient decryption failure into permanent blindness for that device.

Why "just upgrade" is not an answer

Verified 2026-08-24: main and the 2.4.0-rc2 tag both pin baileys: 7.0.0-rc.9, the version we already run. And baileys has no stable 7.x — the newest is 7.0.0-rc14 (2026-07-29), which does not fix this, since the identity-change invalidation exists only in the unmerged PRs. Evolution users have nowhere to upgrade to.

Requests

  1. Fix getMessage() returns { conversation: '' } on miss — Baileys relays an empty message and burns the retry, leaving "Waiting for this message" forever #2705 — cheapest and highest-leverage change here, because it restores the only recovery path that exists for groups. On top of the proposed return undefined: handle the miss separately (if (!rows.length) return undefined) so a genuine database failure can be logged instead of masquerading as a cache miss, and log at warn when getMessage misses.
  2. Mitigate in the Evolution layer, which owns the call into relayMessage: clear sender-key-memory for the group JID before sending (or every N minutes, or when groupMetadata changes). Suggested surface: an opt-in GROUP_SENDER_KEY_RESET=always|interval|off. Cost is redistributing the SenderKey to the group's devices on the next send — 22 devices in our case.
  3. Expose an endpoint/flag to reset a group's sender-key state without restarting the instance and without a manual HDEL in Redis. Today the only route requires direct datastore access, which many hosted users do not have. We currently clear the field hourly from cron as a stop-gap; that should not be necessary.
  4. Secondary observability bug: Message.status for group sends never leaves PENDING on this installation (155 of 155 in the last 24 h), while 1-1 @lid progresses normally. PENDING does not prove non-delivery — messages we confirmed as delivered also sit at PENDING — and that is exactly why the field is useless as an oracle and why this stayed invisible for weeks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions