Description
Discord bot initializes and authenticates successfully but never completes the gateway lifecycle. The bot shows as offline in Discord and never receives inbound messages. WhatsApp channel works fine on the same gateway.
Environment
- OpenClaw: v2026.3.28 (f9b1079)
- Platform: Ubuntu 24.04.4 LTS, Hostinger KVM 2 (8GB RAM)
- Node: v25.8.1
- Discord bot: ID 1484866453525237881
Symptoms
- Gateway logs repeat indefinitely:
[discord] [default] starting provider (@Zach)
[discord] native commands using Carbon reconcile path
[discord] client initialized as 1484866453525237881 (Zach); awaiting gateway readiness
- Bot shows offline in Discord — no presence set
- No
ready or READY log ever appears
- No errors logged — lifecycle fails silently
openclaw channels status reports connected, works
openclaw doctor reports Discord: ok (@Zach) (703ms)
- Health monitor eventually restarts channel for
stale-socket, creating a restart loop
Verified working
- REST API:
curl -H "Authorization: Bot <token>" https://discord.com/api/v10/users/@me returns valid bot info
- Gateway WebSocket (raw): Connecting directly with Node.js
ws module to wss://gateway.discord.gg/?v=10&encoding=json and sending IDENTIFY with the same token → receives HELLO then READY within 1 second
- Token: Reset and verified — same behavior with both old and new token
- Intents: All three privileged intents toggled on in Developer Portal (API still reports
limited flags — may be propagation delay, but raw WS test succeeds regardless)
- Bot membership: Bot is in one guild, confirmed via
/users/@me/guilds
- Session starts remaining: 998/1000
Config (channels.discord section)
{
"discord": {
"enabled": true,
"token": "<redacted>",
"dmPolicy": "open",
"allowFrom": ["*"],
"groupPolicy": "allowlist",
"streaming": "off"
}
}
What I've tried
- Reset bot token in Developer Portal
- Toggled all privileged intents on/off
- Set
gateway.channelHealthCheckMinutes: 0 to stop restart loop
- Added/removed Discord from
plugins.load.paths
- Added
plugins.allow: ["discord"]
- Multiple
openclaw gateway restart cycles
openclaw doctor --fix
- Verified raw Discord gateway WebSocket handshake works from the same server
Root cause hypothesis
The formatDiscordStartupStatusMessage function checks lifecycleGateway?.isConnected which is only set to true when a READY or RESUMED dispatch is received. The runDiscordGatewayLifecycle function is called after the status message but appears to silently fail — no success or error is ever logged. The Discord.js client's login() resolves but the internal gateway supervisor never completes the WebSocket handshake, despite the raw connection working fine from the same process's Node.js runtime.
Expected behavior
Bot should reach ready state, show as online in Discord, and receive DMs/mentions.
Description
Discord bot initializes and authenticates successfully but never completes the gateway lifecycle. The bot shows as offline in Discord and never receives inbound messages. WhatsApp channel works fine on the same gateway.
Environment
Symptoms
readyorREADYlog ever appearsopenclaw channels statusreportsconnected, worksopenclaw doctorreportsDiscord: ok (@Zach) (703ms)stale-socket, creating a restart loopVerified working
curl -H "Authorization: Bot <token>" https://discord.com/api/v10/users/@mereturns valid bot infowsmodule towss://gateway.discord.gg/?v=10&encoding=jsonand sending IDENTIFY with the same token → receives HELLO then READY within 1 secondlimitedflags — may be propagation delay, but raw WS test succeeds regardless)/users/@me/guildsConfig (channels.discord section)
{ "discord": { "enabled": true, "token": "<redacted>", "dmPolicy": "open", "allowFrom": ["*"], "groupPolicy": "allowlist", "streaming": "off" } }What I've tried
gateway.channelHealthCheckMinutes: 0to stop restart loopplugins.load.pathsplugins.allow: ["discord"]openclaw gateway restartcyclesopenclaw doctor --fixRoot cause hypothesis
The
formatDiscordStartupStatusMessagefunction checkslifecycleGateway?.isConnectedwhich is only set totruewhen aREADYorRESUMEDdispatch is received. TherunDiscordGatewayLifecyclefunction is called after the status message but appears to silently fail — no success or error is ever logged. The Discord.js client'slogin()resolves but the internal gateway supervisor never completes the WebSocket handshake, despite the raw connection working fine from the same process's Node.js runtime.Expected behavior
Bot should reach
readystate, show as online in Discord, and receive DMs/mentions.