Skip to content

[Bug]: Discord sends failed during a full network outage are dropped on reconnect (send_attempt_started refuses replay, no reconcileUnknownSend) #100979

Description

@tiffanychum

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_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.

Steps to reproduce

  1. Run openclaw gateway run on a branch with the fix(discord): messages sent during gateway reconnect are silently dropped #100896 reconnect drain (or trigger startup recovery on any build) with channels.discord configured.
  2. 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).
  3. Restore the network and let the Discord gateway reconnect.
  4. 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.

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 (drainQueuedEntry refuses send_attempt_started without reconcileUnknownSend); marker: src/infra/outbound/deliver.ts onPlatformSendStart -> markDeliveryPlatformSendAttemptStarted; failDelivery preserves recoveryState, 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:

  1. When a send fails with a connect-phase error that proves the request never reached Discord (UND_ERR_CONNECT_TIMEOUT, ECONNREFUSED, ENOTFOUND, EAI_AGAIN, ENETUNREACH), clear the send_attempt_started marker in the observed-failure path so the entry stays safely replayable. This is core src/infra/outbound and 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).
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions