Summary
OpenClaw's Discord integration (and potentially all inbound message handlers) silently deadlocks when receiving messages. The gateway accepts messages from Discord, triggers typing indicators, but never processes them. This blocks the lane queue permanently, preventing any messages from being handled until gateway restart.
The root cause is a fire-and-forget promise pattern in message listeners combined with lane queue design that lacks task-level timeouts.
Steps to reproduce
- Run OpenClaw 2026.5.2 with Discord plugin enabled
- Send a DM or channel mention to the bot
- Observe: typing indicator fires, auto-thread created, but no response
- Check logs:
[diagnostic] lane wait exceeded: lane=session:agent:main:discord:channel:<ID> waitedMs=30000+ queueAhead=0
Note: This also affects standard chat/DM channels (not Discord-specific).
Expected behavior
Messages should be processed and responses delivered within a few seconds.
Actual behavior
- ✅ Discord.js client receives message (MESSAGE_CREATE event fires)
- ✅ Typing indicator sent to Discord
- ✅ Auto-thread created in Discord
- ❌ Message handler never executes or hangs
- ❌ Lane queue blocks indefinitely with
queueAhead=0 (no queue; active task stuck)
- ❌ No error logged; handler failure is silently swallowed
- ❌ Gateway remains responsive but Discord messages never complete
Environment
- OpenClaw: 2026.5.2
- Node.js: 22.22.0
- Platform: macOS arm64
- Plugins: bonjour, browser, device-pair, discord, file-transfer, memory-core, phone-control, talk-voice
Root Cause Analysis
File: ~/.openclaw/npm/node_modules/@openclaw/discord/src/monitor/listeners.ts lines 40-49
The Discord message listener uses fire-and-forget pattern:
export class DiscordMessageListener extends MessageCreateListener {
async handle(data: DiscordMessageEvent, client: Client) {
this.onEvent?.();
void Promise.resolve()
.then(() => this.handler(data, client)) // NEVER AWAITED
.catch((err) => { logger.error(...); });
}
}
Problem: The handler runs in background without awaiting. When handler hangs:
- Discord.js returns immediately
- Promise never settles
- Lane queue's
activeTaskIds.size never decrements
- Queue refuses to process next message (maxConcurrent = 1)
- Diagnostic log shows:
lane wait exceeded: queueAhead=0
Proposed Fix
Await the handler with proper error handling:
async handle(data: DiscordMessageEvent, client: Client) {
this.onEvent?.();
try {
await this.handler(data, client);
} catch (err) {
const logger = this.logger ?? discordEventQueueLog;
logger.error(danger(`discord handler failed: ${String(err)}`));
}
}
Related Issues
Severity
Critical — Blocks all inbound message handling. Single stalled handler message makes gateway unusable until restart.
Summary
OpenClaw's Discord integration (and potentially all inbound message handlers) silently deadlocks when receiving messages. The gateway accepts messages from Discord, triggers typing indicators, but never processes them. This blocks the lane queue permanently, preventing any messages from being handled until gateway restart.
The root cause is a fire-and-forget promise pattern in message listeners combined with lane queue design that lacks task-level timeouts.
Steps to reproduce
[diagnostic] lane wait exceeded: lane=session:agent:main:discord:channel:<ID> waitedMs=30000+ queueAhead=0Note: This also affects standard chat/DM channels (not Discord-specific).
Expected behavior
Messages should be processed and responses delivered within a few seconds.
Actual behavior
queueAhead=0(no queue; active task stuck)Environment
Root Cause Analysis
File:
~/.openclaw/npm/node_modules/@openclaw/discord/src/monitor/listeners.tslines 40-49The Discord message listener uses fire-and-forget pattern:
Problem: The handler runs in background without awaiting. When handler hangs:
activeTaskIds.sizenever decrementslane wait exceeded: queueAhead=0Proposed Fix
Await the handler with proper error handling:
Related Issues
Severity
Critical — Blocks all inbound message handling. Single stalled handler message makes gateway unusable until restart.