fix(discord): messages sent during gateway reconnect are silently dropped#100896
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 5:46 PM ET / 21:46 UTC. Summary PR surface: Source -68, Tests +45, Docs +1. Total -22 across 11 files. Reproducibility: yes. Current main lacks Gateway-disconnected retry input for Discord REST requests, and the PR discussion includes a live reconnect proof showing the after-fix nonce delivered exactly once; I did not run a new live Discord repro in this read-only review. Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the scoped request-level retry if maintainers accept the message-delivery risk, keep full-outage reconciliation under #100979, and avoid restoring delivery-level replay. Do we have a high-confidence way to reproduce the issue? Yes. Current main lacks Gateway-disconnected retry input for Discord REST requests, and the PR discussion includes a live reconnect proof showing the after-fix nonce delivered exactly once; I did not run a new live Discord repro in this read-only review. Is this the best way to solve the issue? Yes. Per-REST-request retry is the narrowest maintainable fix for short reconnect windows because a delivery can contain multiple platform writes, while the full-outage durable recovery case belongs to the separate reconciliation work. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against e80e8a2b6730. Label changesLabel justifications:
Evidence reviewedPR surface: Source -68, Tests +45, Docs +1. Total -22 across 11 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
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
Review history (4 earlier review cycles)
|
|
Live behavior proof added (the one gap the earlier review flagged). Setup: real Discord bot + test guild, gateway from this branch on macOS with an isolated state dir, real network cut via Wi-Fi toggle (no mocks, no harness). Scenario (issue #56610 headline path — send attempted while the websocket is down): The send took 33s versus ~2s for a baseline connected send, i.e. the first attempt(s) failed as statusless transport errors and the new disconnected-gateway retry carried it across the reconnect. Delivered Second, harsher run (full outage until in-line retries exhaust) exposed a pre-existing gap outside this PR's scope: the queued entry is marked Filed as #100979 with full logs and two candidate fixes (connect-phase error classification in core, or a Discord |
1a00be4 to
d5b1fcb
Compare
d5b1fcb to
882eb2f
Compare
|
Maintainer refactor and exact-head proof complete.
The longer full-outage |
openclaw#56610) Discord sends that failed while the gateway websocket was reconnecting (close codes 1005/1006) stayed stuck in the outbound delivery queue and were silently dropped. Classify sends that fail while the registered gateway is disconnected as retryable, and drain pending discord queue entries when the gateway reconnects, matching the WhatsApp/Telegram reconnect drains.
Co-authored-by: tiffanychum <[email protected]>
Co-authored-by: tiffanychum <[email protected]>
882eb2f to
331ba3d
Compare
|
Merged via squash.
|
…pped (openclaw#100896) * fix(discord): drain queued outbound deliveries after gateway reconnect (openclaw#56610) Discord sends that failed while the gateway websocket was reconnecting (close codes 1005/1006) stayed stuck in the outbound delivery queue and were silently dropped. Classify sends that fail while the registered gateway is disconnected as retryable, and drain pending discord queue entries when the gateway reconnects, matching the WhatsApp/Telegram reconnect drains. * fix(discord): harden reconnect recovery Co-authored-by: tiffanychum <[email protected]> * refactor(discord): remove unsafe reconnect replay * fix(discord): bound reconnect retry per request Co-authored-by: tiffanychum <[email protected]> * chore(changelog): leave reconnect fix to release flow --------- Co-authored-by: Peter Steinberger <[email protected]>
…pped (openclaw#100896) * fix(discord): drain queued outbound deliveries after gateway reconnect (openclaw#56610) Discord sends that failed while the gateway websocket was reconnecting (close codes 1005/1006) stayed stuck in the outbound delivery queue and were silently dropped. Classify sends that fail while the registered gateway is disconnected as retryable, and drain pending discord queue entries when the gateway reconnects, matching the WhatsApp/Telegram reconnect drains. * fix(discord): harden reconnect recovery Co-authored-by: tiffanychum <[email protected]> * refactor(discord): remove unsafe reconnect replay * fix(discord): bound reconnect retry per request Co-authored-by: tiffanychum <[email protected]> * chore(changelog): leave reconnect fix to release flow --------- Co-authored-by: Peter Steinberger <[email protected]>
…pped (openclaw#100896) * fix(discord): drain queued outbound deliveries after gateway reconnect (openclaw#56610) Discord sends that failed while the gateway websocket was reconnecting (close codes 1005/1006) stayed stuck in the outbound delivery queue and were silently dropped. Classify sends that fail while the registered gateway is disconnected as retryable, and drain pending discord queue entries when the gateway reconnects, matching the WhatsApp/Telegram reconnect drains. * fix(discord): harden reconnect recovery Co-authored-by: tiffanychum <[email protected]> * refactor(discord): remove unsafe reconnect replay * fix(discord): bound reconnect retry per request Co-authored-by: tiffanychum <[email protected]> * chore(changelog): leave reconnect fix to release flow --------- Co-authored-by: Peter Steinberger <[email protected]> (cherry picked from commit da0103f)
Closes #56610
What Problem This Solves
Discord REST requests can fail with statusless transport errors while the Gateway websocket is reconnecting. The normal request retry budget can expire before the reconnect settles, dropping a reply even though the outage is brief.
The earlier version retried whole deliveries and drained durable delivery rows on reconnect. That boundary was unsafe: one delivery can contain several REST writes, so replaying it can duplicate chunks that Discord already accepted. Durable rows in
send_attempt_startedalso cannot be replayed blindly without Discord reconciliation; #100979 remains the owner for that separate full-outage problem.Why This Change Was Made
This revision keeps one canonical retry boundary: the individual Discord REST request.
No new config, protocol, or core surface is added.
User Impact
Short Discord reconnects get additional time to finish the current REST operation without replaying earlier writes from a multi-chunk or multi-media delivery. Partial delivery remains explicit when a later platform write fails. Full-outage durable reconciliation remains tracked by #100979.
Evidence
node scripts/run-vitest.mjs extensions/discord/src/durable-delivery.test.ts extensions/discord/src/retry.test.ts extensions/discord/src/client.test.ts extensions/discord/src/outbound-adapter.test.ts extensions/discord/src/outbound-adapter.interactive-order.test.ts extensions/discord/src/outbound-payload.contract.test.ts— 6 files, 79 tests passed.882eb2fe138023f478e7be774af9c0686769fbcaon the dedicated Discord QA host: blocked all resolved Discord REST/Gateway IPs until both bot gateways reported disconnected; the iptables chain rejected 77 TCP packets. The agent produced noncePR100896-REQUEST-RETRY-1783371460at 20:58:05.733 UTC, the block was removed 2.3 seconds later (after the configured three-attempt window), and the fourth request attempt delivered at 20:58:09.508 UTC. CLI delivery status wassent; an independent Mantis-account read found message1523795212927897640exactly once. The test chain was removed and both accounts reconnected. The subsequent rebase only incorporated unrelatedmainchanges.