SWAGcommands
Commands

Responses and deferral

Return a value, defer slow interactions, or reply yourself.

The easy path is to return something from the callback. SWAGcommands accepts a string, a discord.js MessagePayload, or the options object supported by the Discord response method for that invocation.

callback: async () => ({
  content: "Here's the result",
  embeds: [embed],
  components: [row],
})
InvocationWhat SWAGcommands calls
Fresh slash or context-menu interactioninteraction.reply(result)
Deferred interactioninteraction.editReply(result)
Message command with reply: truemessage.reply(result)
Other message commandmessage.channel.send(result)

undefined means “I handled this myself” or “send nothing.” The framework checks specifically for undefined, so an empty string is still handed to Discord and may be rejected there.

Slow work: defer first

const report = {
  type: CommandType.SLASH,
  description: "Generate a report",
  deferReply: { ephemeral: true },
  callback: async () => {
    const result = await makeReport();
    return { content: result };
  },
} satisfies CommandObject;

deferReply: true acknowledges an interaction before the callback and later edits that reply. The object form with ephemeral: true makes the deferred reply private. For message commands, deferReply sends a typing indicator instead. A subcommand leaf can override its root's setting.

If your callback calls interaction.reply() directly, return undefined to avoid a second response. Duplicate acknowledgements, failed sends, and callback failures are reported through structured errors. onError lets you log or handle them centrally.

On this page