On this page

On this page

Mainstream messaging

Discord troubleshooting

Symptom-first checks for a Discord account that is not behaving.

Each account start logs [account] starting account (reason: ...) at info level. The reason distinguishes startup, manual starts, automatic retries, health recovery, config/plugin/secret reloads, and host-thaw recovery. A Discord socket reconnect or resume stays inside the existing account lifetime and does not produce this line. An event-loop stall label identifies work while its named operation is active; it does not by itself establish that an account restarted.

Troubleshooting

Used disallowed intents or bot sees no guild messages
  • enable Message Content Intent
  • enable Server Members Intent when you depend on user/member resolution
  • restart gateway after changing intents
Guild messages blocked unexpectedly
  • verify groupPolicy
  • verify guild allowlist under channels.discord.guilds
  • if a guild channels map exists, only listed channels are allowed
  • verify requireMention behavior and mention patterns

The Control UI channel details and openclaw channels status warn when the effective policy is allowlist but no guilds are configured. Add your server under channels.discord.guilds, or the account's guilds map when overridden. An explicit channels.discord.accounts.default.guilds map also overrides the top-level map, even when the account map is empty.

If status reports a deferred configuration reload, wait for active work to finish and refresh. A successful channel stop/start does not apply unpublished configuration. The warning distinguishes waiting to publish configuration from channel work deferred after publication; connection health alone does not confirm that a policy change has applied.

Useful checks:

bash
openclaw doctoropenclaw channels status --probeopenclaw logs --follow
Require mention false but still blocked

Common causes:

  • groupPolicy="allowlist" without matching guild/channel allowlist
  • requireMention configured in the wrong place (must be under channels.discord.guilds or a channel entry)
  • sender blocked by guild/channel users allowlist
Long-running Discord turns or duplicate replies

Typical logs:

  • Slow listener detected ...
  • stuck session: sessionKey=agent:...:discord:... state=processing ...

Discord does not apply a channel-owned timeout to queued agent turns. Message listeners hand off immediately, and queued Discord runs preserve per-session ordering until the session/tool/runtime lifecycle completes or aborts the work.

Gateway metadata lookup timeout warnings

OpenClaw fetches Discord /gateway/bot metadata before connecting. Transient failures fall back to Discord's default gateway URL and are rate-limited in logs.

The metadata timeout defaults to 30 seconds. OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS can override it for unusual host environments.

Gateway READY timeout restarts

OpenClaw waits for Discord's gateway READY event during startup and after runtime reconnects. Multi-account setups with startup staggering can need a longer startup READY window than the default.

Startup waits 15 seconds and runtime reconnects wait 30 seconds. OPENCLAW_DISCORD_READY_TIMEOUT_MS and OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS remain available for unusual host environments.

Permissions audit mismatches

channels status --probe permission checks only work for numeric channel IDs.

If you use slug keys, runtime matching can still work, but check cannot fully verify permissions.

DM and pairing issues
  • DM disabled: channels.discord.dm.enabled=false
  • DM policy disabled: channels.discord.dmPolicy="disabled" (legacy: channels.discord.dm.policy)
  • awaiting pairing approval in pairing mode
Bot to bot loops

Bot-authored messages are accepted by default under normal mention and access rules.

Keep mention and allowlist rules appropriate for the room. Set channels.discord.allowBots=false to disable bot-triggered turns, or channels.discord.allowBots="mentions" to only accept bot messages that mention the bot. These settings do not hide accessible bot-authored history or human-selected reply context. In "mentions" mode, reply-ping metadata alone does not count. Bot replies need an active native mention or a configured text/transcript mention outside Markdown code.

OpenClaw also ships shared bot loop protection. Whenever allowBots lets bot-authored messages reach dispatch, Discord maps the inbound event to (account, channel, bot pair) facts and the generic pair guard suppresses the pair after it crosses the configured event budget. The guard bounds rapid two-bot loops; exchanges below the budget can continue. It does not affect human messages or one-shot bot replies that stay under the budget.

Default settings (active whenever bot-authored messages are admitted):

  • maxEventsPerWindow: 20 -- bot pair can exchange 20 messages within the sliding window
  • windowSeconds: 60 -- sliding window length
  • cooldownSeconds: 60 -- once the budget trips, every additional bot-to-bot message in either direction is dropped for one minute

Configure the shared default once under channels.defaults.botLoopProtection, then override Discord when a legitimate workflow needs more headroom. Precedence is:

  • channels.discord.accounts.<account>.botLoopProtection
  • channels.discord.botLoopProtection
  • channels.defaults.botLoopProtection
  • built-in defaults

Discord uses the generic maxEventsPerWindow, windowSeconds, and cooldownSeconds keys.

json5
{  channels: {    defaults: {      botLoopProtection: {        maxEventsPerWindow: 20,        windowSeconds: 60,        cooldownSeconds: 60,      },    },    discord: {      // Optional Discord-wide override. Account blocks override individual      // fields and inherit omitted fields from here.      botLoopProtection: {        maxEventsPerWindow: 4,      },      accounts: {        alpha: {          // Alpha listens to other bots only when they mention it.          allowBots: "mentions",        },        bravo: {          // Bravo listens to all bot-authored Discord messages.          allowBots: true,          mentionAliases: {            // Lets Bravo write an Alpha Discord mention with the configured user id.            Alpha: "ALPHA_DISCORD_USER_ID",          },          botLoopProtection: {            // Allow up to five messages per minute before suppressing the pair.            maxEventsPerWindow: 5,            windowSeconds: 60,            cooldownSeconds: 90,          },        },      },    },  },}
Voice STT drops with DecryptionFailed(...)
  • run OpenClaw 2026.2.24 or newer (openclaw update), the release that added the Discord voice receive recovery logic (#25861)
  • confirm channels.discord.voice.daveEncryption=true (default)
  • start from channels.discord.voice.decryptionFailureTolerance=24 (upstream default) and tune only if needed
  • watch logs for:
    • discord voice: DAVE decrypt failures detected
    • discord voice: repeated decrypt failures; attempting rejoin
  • if failures continue after automatic rejoin, collect logs and compare against the upstream DAVE receive history in discord.js #11419 and discord.js #11449
Was this useful?