You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Bug]: Discord sends failed during a full network outage are dropped on reconnect (send_attempt_started refuses replay, no reconcileUnknownSend) #100979
A Discord outbound message that fails during a full network outage is permanently dropped on gateway reconnect: the delivery-queue entry is marked send_attempt_started at platform-send start, Discord has no durableFinal.reconcileUnknownSend adapter, so the reconnect drain refuses blind replay and moves the entry to failed — observed live on a real Wi-Fi cut.
Cut the machine's network (Wi-Fi off) and, while it is down, run openclaw message send --channel discord --target channel:<id> -m "test". In-line retries exhaust with UND_ERR_CONNECT_TIMEOUT; the CLI exits 1 and the queue keeps a pending entry with recoveryState: "send_attempt_started" (marked by markDeliveryPlatformSendAttemptStarted before the failure was observed).
Restore the network and let the Discord gateway reconnect.
The reconnect drain finds the entry but refuses to replay it.
Expected behavior
The queued message is delivered after connectivity returns (that is the purpose of the durable outbound delivery queue), or at minimum the operator gets a surfaced failure. The issue #56610 report is "Discord messages silently lost during gateway reconnect"; the full-outage variant still loses the message.
Actual behavior
Gateway log from the live repro (2026-07-06, local proof run):
22:50:06 discord gateway: Gateway websocket opened
22:50:07 [discord] Delivery entry 155a9da3-9648-4488-9fee-66cf47eacbcb delivery state is send_attempt_started; refusing blind replay without adapter reconciliation
22:50:07 [discord] Discord reconnect drain: retry failed for entry 155a9da3-9648-4488-9fee-66cf47eacbcb: delivery state is send_attempt_started; refusing blind replay without adapter reconciliation
The entry ends up status=failed in delivery_queue_entries and the message is never delivered.
See Actual behavior. Guard: src/infra/outbound/delivery-queue-recovery.ts:394-470 (drainQueuedEntry refuses send_attempt_started without reconcileUnknownSend); marker: src/infra/outbound/deliver.tsonPlatformSendStart -> markDeliveryPlatformSendAttemptStarted; failDelivery preserves recoveryState, so a cleanly observed pre-dispatch failure is indistinguishable from a crash mid-send.
Implement durableFinal.reconcileUnknownSend for Discord. Discord's message-create API supports nonce + enforce_nonce, which gives server-side idempotency for recent sends and could also make replay safe by construction.
Found while producing the live reconnect proof for #100896; the in-line retry path from that PR was verified delivered-exactly-once in the same session, this full-outage queue path is the remaining gap.
Summary
A Discord outbound message that fails during a full network outage is permanently dropped on gateway reconnect: the delivery-queue entry is marked
send_attempt_startedat platform-send start, Discord has nodurableFinal.reconcileUnknownSendadapter, so the reconnect drain refuses blind replay and moves the entry tofailed— observed live on a real Wi-Fi cut.Steps to reproduce
openclaw gateway runon a branch with the fix(discord): messages sent during gateway reconnect are silently dropped #100896 reconnect drain (or trigger startup recovery on any build) withchannels.discordconfigured.openclaw message send --channel discord --target channel:<id> -m "test". In-line retries exhaust withUND_ERR_CONNECT_TIMEOUT; the CLI exits 1 and the queue keeps a pending entry withrecoveryState: "send_attempt_started"(marked bymarkDeliveryPlatformSendAttemptStartedbefore the failure was observed).Expected behavior
The queued message is delivered after connectivity returns (that is the purpose of the durable outbound delivery queue), or at minimum the operator gets a surfaced failure. The issue #56610 report is "Discord messages silently lost during gateway reconnect"; the full-outage variant still loses the message.
Actual behavior
Gateway log from the live repro (2026-07-06, local proof run):
The entry ends up
status=failedindelivery_queue_entriesand the message is never delivered.OpenClaw version
2026.6.11 (4820a3a) + PR #100896
Operating system
macOS 15.5 (darwin 25.5.0)
Install method
pnpm dev (source checkout)
Model
n/a (CLI
message send, no model involved)Provider / routing chain
openclaw CLI -> local gateway -> Discord REST
Logs
See Actual behavior. Guard:
src/infra/outbound/delivery-queue-recovery.ts:394-470(drainQueuedEntryrefusessend_attempt_startedwithoutreconcileUnknownSend); marker:src/infra/outbound/deliver.tsonPlatformSendStart->markDeliveryPlatformSendAttemptStarted;failDeliverypreservesrecoveryState, so a cleanly observed pre-dispatch failure is indistinguishable from a crash mid-send.Impact and severity
Additional information
Two candidate fixes, both compatible with the duplicate-send safety that the guard protects:
UND_ERR_CONNECT_TIMEOUT,ECONNREFUSED,ENOTFOUND,EAI_AGAIN,ENETUNREACH), clear thesend_attempt_startedmarker in the observed-failure path so the entry stays safely replayable. This is coresrc/infra/outboundand would benefit every channel behind the same guard (siblings: Signal final replies can be stranded by gateway restart after send_attempt_started #90233 for Signal, [Bug]: Discord component interactions stall 6–12 min in gateway delivery pipeline (send_attempt_started stuck) #95548 for Discord interactions).durableFinal.reconcileUnknownSendfor Discord. Discord's message-create API supportsnonce+enforce_nonce, which gives server-side idempotency for recent sends and could also make replay safe by construction.Found while producing the live reconnect proof for #100896; the in-line retry path from that PR was verified delivered-exactly-once in the same session, this full-outage queue path is the remaining gap.