Skip to content

Discord interactive components: reusable:false expires per-button not per-panel, and editMessage broken due to message/content field mismatch #54233

Description

@fujiwarakasei

Summary

Two related bugs found while testing Discord interactive components (Components v2).


Bug 1: reusable: false expires per-button instead of per-panel

Expected behavior

When any button in a reusable: false component panel is clicked, the entire panel should be consumed — all buttons become expired and no further callbacks are delivered to the agent.

Actual behavior

Each button has its own independent entry. Clicking button A only consumes button A's entry; button B remains active. This means:

  • Clicking the same button twice → second click correctly shows ephemeral "This component has expired." ✅
  • Clicking button A then button B → button B still fires a callback ❌

Root cause (from source)

In dist/discord-CcCLMjHw.js:

const consumed = resolveDiscordComponentEntry({
    id: parsed.componentId,
    consume: !entry.reusable  // consumes only this button's entry
});

consume operates at individual button entry level, not panel level.

Impact

Breaks the safety guarantee of single-use confirmation panels (e.g. "confirm delete?"). A user clicking Cancel first, then Confirm, causes both callbacks to fire — the agent cannot rely on reusable: false to enforce single-use semantics across a multi-button panel.

Reproduction

  1. Send message with reusable: false and two buttons (✅ Confirm, ❌ Cancel)
  2. Click ❌ Cancel → callback fires, entry consumed
  3. Click ✅ Confirm → callback fires again (should not)

Bug 2: message tool edit action broken for Discord — message vs content field mismatch

Expected behavior

message tool with action: "edit" should allow editing a Discord message's content.

Actual behavior

Edit always fails with Error (underlying: content required).

Root cause (from source)

The message tool schema exposes text content as the message field. But the Discord editMessage handler reads from content:

// Discord editMessage handler in dist/discord-CcCLMjHw.js:
const content = readStringParam(params, "content", { required: true });
// ↑ reads "content" — but message tool passes "message" field

readSnakeCaseParamRaw only handles camelCase↔snake_case aliasing; there is no messagecontent alias. So content is always undefined, causing a ToolInputError: content required and the edit fails every time.

Impact

It is impossible to edit a Discord message via the message tool. This blocks a key workaround for Bug 1 (editing the message to remove buttons after first click).


Environment

  • OpenClaw version: 2026.3.13
  • Platform: macOS Darwin arm64
  • Channel: Discord

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions