openclaw - ✅(Solved) Fix [Bug]: Discord gateway READY event never fires — bot online but unresponsive (race condition) [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#74617Fetched 2026-04-30 06:22:11
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
labeled ×2commented ×1cross-referenced ×1

Discord.js gateway READY event never fires after openclaw startup, leaving the bot online but permanently unresponsive. A raw WebSocket test confirms the gateway is reachable and functional from the same container, indicating the bug is in openclaw's Discord plugin event registration or event-loop scheduling.

Error Message

  1. Gateway READY event never fires. No error, no timeout, no gateway close event. The gateway READY event never fires. Logs show initialization completes up to "awaiting gateway readiness" and then silently stops — no error, no gateway close, no timeout. The bot appears online in Discord (the websocket connection is established at the transport level) but never processes messages. The raw websocket test from the same container proves the gateway is reachable: (nothing after this — no error, no gateway close, no timeout)

Root Cause

Discord.js gateway READY event never fires after openclaw startup, leaving the bot online but permanently unresponsive. A raw WebSocket test confirms the gateway is reachable and functional from the same container, indicating the bug is in openclaw's Discord plugin event registration or event-loop scheduling.

Fix Action

Fix / Workaround

No workaround has been found other than repeatedly restarting the container until the gateway connects.

PR fix notes

PR #15: fix(discord): detect READY when WebSocket opened before lifecycle debug listener registered

Description (problem / solution / changelog)

Fixes #74617.

Root cause

Carbon calls registerClient() (and thus connect()) synchronously during new Client() construction, but the async gateway-info fetch means the WebSocket can open — and "WebSocket connection opened" fires on the gateway emitter — during the await-ed setup steps in monitorDiscordProvider, before runDiscordGatewayLifecycle registers its debug listener.

When this happens isConnected is still false (READY not yet received), so the existing isConnected startup guard misses it and no hello-connected poll is started. READY then arrives with nothing listening, so connected status is never pushed. The lifecycle behaves as if the channel is permanently disconnected until an explicit reconnect fires a new "WebSocket connection opened" event that the listener does catch.

This explains the 9/10 failure rate: most channel restarts take long enough that the gateway's TCP + HELLO handshake completes before runDiscordGatewayLifecycle runs, but READY hasn't been received yet — falling squarely in the race window.

Fix

After registering the debug listener, check whether gateway.ws.readyState is already 1 (WebSocket.OPEN). If so, "WebSocket connection opened" must have been missed; start the hello-connected poll immediately so READY is still detected when it arrives.

The poll+30 s stall-timeout block is refactored into a startHelloWatch(at) helper to avoid duplicating the logic between onGatewayDebug and the new startup guard.

Regression tests

Two new cases in provider.lifecycle.test.ts:

  1. startup race — gateway has ws.readyState=1 at lifecycle start, no "WebSocket connection opened" event emitted, READY arrives after → lifecycle must push connected: true within one poll interval (250 ms).
  2. no spurious poll — gateway has no ws property (not yet connecting) → no poll starts and no false connected: true is pushed.

Testing

pnpm tsgo   # zero errors
pnpm test src/discord/monitor/provider.lifecycle.test.ts
# 13/13 pass

Generated by Claude Code

<!-- devin-review-badge-begin -->
<a href="https://app.devin.ai/review/suboss87/openclaw/pull/15" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open in Devin Review"> </picture> </a> <!-- devin-review-badge-end -->

Changed files

  • src/commands/agent.test.ts (modified, +67/-0)
  • src/commands/agent.ts (modified, +18/-0)
  • src/cron/service.cron-invalid-expr.test.ts (added, +133/-0)
  • src/cron/service/ops.ts (modified, +9/-0)
  • src/cron/validate-timestamp.ts (modified, +23/-0)
  • src/discord/monitor/provider.lifecycle.test.ts (modified, +81/-0)
  • src/discord/monitor/provider.lifecycle.ts (modified, +55/-37)
  • src/gateway/server-methods/cron.ts (modified, +18/-1)

Code Example

WS opened in 142 ms
OP: 10 (Hello) in 142 ms
Heartbeat ACK in 242 ms
OP: 0 Event: READY in 398 ms

---

20:39:18 discord starting provider (@bob)
20:39:22 discord users resolved: user:1066032302855036978->1066032302855036978
20:39:26 embedded acpx runtime backend ready
20:39:26 discord client initialized as 1483146131033555064 (bob); awaiting gateway readiness
(nothing after this — no error, no gateway close, no timeout)

---

WS opened in 142 ms
OP: 10 (Hello) in 142 ms
Heartbeat ACK in 242 ms
OP: 0 Event: READY in 398 ms

---

{"username":"bob","id":"1483146131033555064","verified":true,"bot":true}

---

{"total":1000,"remaining":991,"reset_after":...}

---
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

Bug Report for: openclaw/openclaw

Title

[Bug]: Discord gateway READY event never fires — bot online but unresponsive (race condition)

Template Field Responses

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Discord.js gateway READY event never fires after openclaw startup, leaving the bot online but permanently unresponsive. A raw WebSocket test confirms the gateway is reachable and functional from the same container, indicating the bug is in openclaw's Discord plugin event registration or event-loop scheduling.

Steps to reproduce

  1. Start openclaw 2026.4.23 (or 2026.4.26) with a Discord channel configured.
  2. Observe logs: discord client initialized as <BOT_ID> (<bot_name>); awaiting gateway readiness
  3. Gateway READY event never fires. No error, no timeout, no gateway close event.
  4. Bot appears online in Discord but never responds to messages. Sessions stuck in "processing" state indefinitely.
  5. Repeat restarts produce the same result approximately 9 out of 10 times. Rarely (~1 in 10 restarts), the gateway connects successfully and the bot works normally until next restart.

Expected behavior

The Discord.js gateway READY event should fire within a few seconds of client.login(), after which the bot should respond to messages. A raw WebSocket connection to the same gateway from the same container receives the READY event in 398ms, so the network and gateway are functional.

Actual behavior

The gateway READY event never fires. Logs show initialization completes up to "awaiting gateway readiness" and then silently stops — no error, no gateway close, no timeout. The bot appears online in Discord (the websocket connection is established at the transport level) but never processes messages. The raw websocket test from the same container proves the gateway is reachable:

WS opened in 142 ms
OP: 10 (Hello) in 142 ms
Heartbeat ACK in 242 ms
OP: 0 Event: READY in 398 ms

Discord API /users/@me also returns valid bot info, and session start limits show 991/1000 remaining (no rate limiting).

OpenClaw version

2026.4.23 (also reproduced on 2026.4.26/latest)

Operating system

Linux — Docker container (ghcr.io/openclaw/openclaw:2026.4.23) on Ubuntu host, kernel 6.8.0-110-generic

Install method

Docker (ghcr.io/openclaw/openclaw:2026.4.23@sha256:1e6e1b562bbaa4816005f7a379fe2f5bc894289a08c0631f64263d705b81d809)

Model

Multiple models configured via OpenRouter; model selection is not relevant to this bug — the issue occurs before any model call is made.

Provider / routing chain

openclaw -> openrouter -> (various models). OpenRouter model calls work fine from the container; the issue is isolated to the Discord.js gateway initialization.

Additional provider/model setup details

The Discord channel is configured with a standard bot token. No Discord proxy or custom gateway URL is in use. Other channels (if any) are unaffected. The routing chain through OpenRouter functions correctly when the Discord gateway does connect.

Logs, screenshots, and evidence

Log timeline showing the stuck state:

20:39:18 discord starting provider (@bob)
20:39:22 discord users resolved: user:1066032302855036978->1066032302855036978
20:39:26 embedded acpx runtime backend ready
20:39:26 discord client initialized as 1483146131033555064 (bob); awaiting gateway readiness
(nothing after this — no error, no gateway close, no timeout)

Raw WebSocket test from the same container (successful):

WS opened in 142 ms
OP: 10 (Hello) in 142 ms
Heartbeat ACK in 242 ms
OP: 0 Event: READY in 398 ms

Discord API validation (successful):

{"username":"bob","id":"1483146131033555064","verified":true,"bot":true}

Session start limit check:

{"total":1000,"remaining":991,"reset_after":...}

Impact and severity

  • Affected: All users running openclaw 2026.4.23+ with Discord channel enabled in Docker deployments.
  • Severity: High — completely blocks the Discord channel. The bot appears online but is non-functional.
  • Frequency: Intermittent, approximately 9 out of 10 restarts. When it does connect (~10% of restarts), the bot works normally until the next restart.
  • Consequence: Agents never respond to Discord messages. Sessions accumulate in "processing" state. Manual intervention (repeated container restarts) is required to get the bot operational.

Additional information

The intermittent nature (roughly 1 in 10 restarts succeeds) strongly suggests a race condition. Possible causes:

  1. The client.login() call completes but the READY event handler is not registered in time, or is garbage-collected before the event fires.
  2. Synchronous work on the event loop during channel initialization (e.g., loading sessions, memory, or other plugins) blocks the event loop long enough that the Discord.js heartbeat/response cycle fails silently.
  3. The READY event fires but is swallowed by openclaw's plugin lifecycle (e.g., the plugin hasn't finished initializing so the event is discarded).

No workaround has been found other than repeatedly restarting the container until the gateway connects.

First observed in: 2026.4.23 Last confirmed in: 2026.4.26/latest Node.js version inside container: v24.14.0

Steps to reproduce

mentioned above

Expected behavior

mentioned above

Actual behavior

mentioned above

OpenClaw version

2026.4.26

Operating system

ubnto

Install method

No response

Model

glm 5 turbo

Provider / routing chain

glm

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

No response

extent analysis

TL;DR

The most likely fix for the Discord gateway READY event not firing is to investigate and address a potential race condition in the openclaw Discord plugin event registration or event-loop scheduling.

Guidance

  • Review the event registration process in the Discord plugin to ensure the READY event handler is properly registered before the client.login() call completes.
  • Investigate potential synchronous work on the event loop during channel initialization that may block the event loop and cause the Discord.js heartbeat/response cycle to fail silently.
  • Consider adding logging or debugging statements to track the execution flow and identify where the issue occurs.
  • Verify that the READY event is not being swallowed by openclaw's plugin lifecycle by checking the plugin's initialization process.

Example

No code snippet is provided as the issue is more related to the event registration and event-loop scheduling, which requires a deeper understanding of the openclaw Discord plugin implementation.

Notes

The intermittent nature of the issue (approximately 9 out of 10 restarts) suggests a race condition, which can be challenging to reproduce and debug. The provided raw WebSocket test and Discord API validation results indicate that the issue is isolated to the openclaw Discord plugin.

Recommendation

Apply a workaround by implementing a retry mechanism for the Discord gateway connection, allowing the bot to recover from the intermittent failure. This can be done by adding a retry loop around the client.login() call, with a reasonable delay between attempts.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

mentioned above

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: Discord gateway READY event never fires — bot online but unresponsive (race condition) [1 pull requests, 1 comments, 2 participants]