Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Troubleshooting

Discord shows “This interaction failed” (or “The application did not respond”) when it gets no valid answer in time. Composure answers handler errors itself, with an ephemeral message the user reads and a log line with the cause, so Discord’s own failure usually means the answer never arrived or Discord rejected it. Start with the logs: wrangler tail or Workers Logs on Cloudflare, stderr on a server.

“This interaction failed”

CauseWhat you seeFix
No answer within 3 seconds“The application did not respond”; the handler finishes laterAnswer with ctx.defer(..) and do the slow part in Background Work (REST and deferring). On Workers, a cold start plus slow REST calls before answering can be enough
Signature or public key mismatch401 in the logs; the Endpoint URL won’t saveSet DISCORD_PUBLIC_KEY to the public key of the application whose Endpoint URL points at the bot, not another one’s (development and production apps differ)
Configuration failed to load500 on Workers, logged on the isolate’s first requestA missing secret or var, or an error from .with_credentials / .with_data; set it and retry
Discord rejected the responseThe handler ran, nothing is logged as an errorA response Discord refuses: more than 10 embeds, an empty message, a component built by hand over its limits. Views are checked before answering (counts, lengths, repeated select option values) and fail as a handler error instead. Compare the response with Discord’s limits; Testing shows the JSON
Components V2 with content or embedsAn error naming the fieldA Components V2 message (a Container, a View) carries its text in text displays: move content and embeds into components

Errors the user sees

MessageCauseFix
“Unknown command.”The App has no Command with that name and type: Discord’s Commands are out of sync with the deployed codecargo run --bin sync -- --check shows the differences; sync, or deploy the code first (Deploying)
“Something went wrong handling this interaction.”A handler returned an error, or an Option couldn’t be readThe log line has the error and its causes (sources)
The same, from a button posted before a deployIts custom_id was encoded by an older version of the handler: the state’s fields changedKeep the state’s fields compatible, or give the handler a new prefix so old buttons get the “not handled” answer instead
The same, logged as “custom_id is N characters”The state doesn’t fit Discord’s 100 charactersKeep less in the custom_id: an id, with the rest in storage
“This bot does not handle components.”No handler for the custom_id’s prefixList the handler (or the View) in the App, or set a fallback (Components)

REST errors

ctx.bot() and ctx.client() calls return rest::Error, with Discord’s JSON error code when it sent one.

StatusCauseFix
401 from ctx.bot()DISCORD_TOKEN is missing, wrong, or reset in the Developer PortalSet the current bot token
401 from ctx.client()The Interaction’s token expired: follow-ups and edits work for 15 minutesFinish within 15 minutes, or post with ctx.bot()
403, code 50013 (Missing Permissions)The bot lacks a permission in that channel, or the target’s role is above the bot’sGrant the permission (the invite link’s permissions), or move the bot’s role up
403, code 50001 (Missing Access)The bot can’t see the channel or isn’t in the server, as with a user-installed app used in a server without the botCheck ctx.interaction().common.authorizing_integration_owners before calling the bot client, or answer through ctx.client(), which needs no membership
429Rate limited for longer than the client waits (2 seconds by default)with_max_rate_limit_wait(..) on the client, or do less per Interaction

Other surprises

  • A Command doesn’t show up. Sync it; global Commands can take a moment to appear in the client, and a guild-only Command shows only where it was sent. Restarting Discord (Ctrl+R) refreshes its cache.
  • An ephemeral deferral turned the answer ephemeral. Ephemerality is decided by the first response: Ephemeral(ctx.defer(..)) makes the final message ephemeral too.
  • Webhook Events don’t arrive. The Webhook Events URL must end in /events, and each event must be enabled in the Developer Portal.