Skip to content

[Bug] Discord interaction handler AbortError floods log when event loop is saturated — no user-facing recovery #77716

Description

@slideshow-dingo

Bug Summary

When a Discord slash command (e.g. /new) is issued while the Node.js event loop is saturated (>95% utilization), the Discord interaction handler hits an internal timeout and emits AbortError: This operation was aborted with no user-facing recovery message posted to the channel. The user's turn is silently dropped.

Environment

  • OpenClaw: 2026.5.3-1
  • Node.js: 22.22.2 (Linux)
  • Channel: Discord
  • Surface: guild text channel

Steps to Reproduce

  1. Have the gateway under heavy load (parallel subagent spawns, compaction, Honcho hook failures)
  2. EL utilization climbs to >95% (P99 ELD 6000ms+)
  3. Issue /new command in Discord channel
  4. Observe in gateway log: [discord] interaction handler failed: AbortError: This operation was aborted
  5. No message appears in Discord — the user gets no feedback that their command was received

Observed Log

2026-05-05T15:31:11 [WARN] liveness warning: reasons=event_loop_delay,event_loop_utilization,cpu interval=30s eventLoopDelayP99Ms=6530.5 eventLoopDelayMaxMs=6555.7 eventLoopUtilization=0.967 cpuCoreRatio=1.053 active=1 waiting=0
2026-05-05T15:31:17 [ERROR] discord interaction handler failed: AbortError: This operation was aborted

Root Cause Analysis

The Discord interaction handler has an internal timeout (observed: ~6s between liveness warning and AbortError). When ELD is 6500ms+, the handler's work queue cannot drain within that window, causing the AbortError. The error is caught and logged, but no fallback reply is sent to the Discord channel.

This is related to but distinct from: #69249 (gateway restart aborts) and #71127 (stuck sessions never aborted).

Expected Behavior

When the interaction handler catches an AbortError, it should either:

  1. Post a user-visible message to the channel: "Your command was received but I couldn't process it due to high load. Please try again in a moment."
  2. Queue the command for retry once the EL recovers
  3. Both

Impact

  • User trust erosion: command appears to be ignored
  • Debugging difficulty: no channel feedback means users don't know their command was received
  • Distinguishability: hard to tell apart from a dead bot vs. a saturated bot

Suggested Fix

In the Discord plugin interaction handler error path, add a channel-safe fallback reply before re-throwing or logging:

// After catching AbortError in interaction handler
await sendChannelMessage(channelId, "I'm experiencing high load right now. Your command was received — please give me a moment and try again.");
// Then log and proceed

A more robust fix would be a general channelHealthCheck that marks channels as degraded when EL is saturated and routes fallback messages accordingly.

Internal Reference

  • Handler timeout: appears to be ~6s from liveness warning to abort
  • Error string: AbortError: This operation was aborted
  • Log location: subsystem-DmUr_Z7J.js:150

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions