Skip to content

Discord approval buttons fail with "This interaction failed" — defer misses the 3s gateway ack window (regression) #1030

Description

@Aaronontheweb

Summary

Discord tool-approval buttons are broken. When the agent posts an approval prompt and the user clicks any approve/deny button, Discord shows "This interaction failed" and the tool call is never acknowledged. This was reported by a user and is a confirmed NetClaw regression.

User-facing symptom

  • Discord integration is otherwise working — the user can converse with the agent over Discord.
  • When the agent requests approval for a tool use and the user clicks an approval button, Discord immediately shows "This interaction failed."
  • The approval never reaches the session — the tool call stalls.

Logs (sanitized)

Promoted Discord session to thread reply_channel=<channel-id>
[WRN] Netclaw.Channels.Discord.Transport.DiscordNetGatewayClient: Failed to defer Discord button interaction <interaction-id>
System.TimeoutException: Cannot defer an interaction after 3 seconds of no response/acknowledgement
   at Discord.WebSocket.SocketMessageComponent.DeferAsync(Boolean ephemeral, RequestOptions options)
   at Netclaw.Channels.Discord.Transport.DiscordNetGatewayClient.OnButtonExecutedAsync(SocketMessageComponent component)

Diagnosis

Discord requires a button interaction to be acknowledged within 3 seconds of the click, or it is rejected with "This interaction failed".

In DiscordNetGatewayClient.OnButtonExecutedAsync (src/Netclaw.Channels.Discord/Transport/DiscordNetGatewayClient.cs:140), await component.DeferAsync() is already the first statement of the handler (line 144) — so the handler body is not the source of the delay. The 3-second window is being consumed before our handler runs, i.e. the Discord.NET gateway event loop appears to be congested/blocked, so the ButtonExecuted event is dispatched late and even an immediate DeferAsync() misses the deadline.

The log line immediately preceding the failure is notable:

Promoted Discord session to thread reply_channel=<channel-id>

emitted from DiscordSessionBindingActor.cs:1065. The session-promotion-to-thread path running on/around the gateway event dispatch is a strong candidate for what is stalling the loop.

A likely regression candidate worth bisecting first: #982 ("Button approvals route by SessionId"), which reworked the approval-button routing path. If the new routing does more synchronous work before the handler can defer (or changed how/when the handler is invoked relative to gateway dispatch), that would produce exactly this symptom.

Impact

Tool approvals over Discord are non-functional. Any workflow that requires the user to approve a tool call cannot proceed — this blocks the core approval/consent flow for Discord users.

Suggested investigation

  • Confirm whether ButtonExecuted dispatch is being delayed by a blocked Discord.NET gateway task (Discord.NET runs event handlers on the gateway task by default; a slow handler stalls subsequent dispatch).
  • Check whether the session-to-thread promotion (DiscordSessionBindingActor) or the post-fix(channels): route button approvals by SessionId so passivated gateways don't drop responses (#979) #982 approval routing performs blocking work on the gateway thread.
  • Ensure the interaction is deferred immediately and independently of any actor/session resolution work — the ack must not wait on session promotion, ACL checks, or routing.
  • Consider whether OnMessageReceivedAsync / other gateway handlers can hold up the loop long enough to eat the 3s budget for a concurrent button click.

Repro

  1. Configure Discord integration.
  2. Have the agent request a tool that needs approval.
  3. Click any approval button on the prompt.
  4. Observe "This interaction failed" in Discord and the TimeoutException in the daemon logs.

Environment

  • Channel: Discord
  • Component: Netclaw.Channels.DiscordDiscordNetGatewayClient.OnButtonExecutedAsync

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingchannelsDiscord, Slack, and other channels.reliabilityRetries, resilience, graceful degradation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions