Encountered error while handling an interaction handler run method for interaction-handler

Been trying to debug an interaction error and haven't been able to figure out why it's erroring. There isn't a single method on the interaction which is allowing me to edit a reply or send a new one and I am confused. The code I am using is code I'm using on other interactions and it works perfectly fine, so I'm confused. GroupButton.ts button for groups
public run(interaction: ButtonInteraction) {
// If the group is undefined then we should not run
if (!this.group) return;

// We can now run the command
return replyWithCommands(interaction, this.group.name);
}
public run(interaction: ButtonInteraction) {
// If the group is undefined then we should not run
if (!this.group) return;

// We can now run the command
return replyWithCommands(interaction, this.group.name);
}
replyToInteraction.ts Interaction util for my help command
export async function replyWithCommands(
interaction: ChatInputCommandInteraction | MessageComponentInteraction,
groupName: string
) {
await autoDeferReply(interaction);

// Check the group exists
const group = await getGroup(interaction.client, interaction, groupName);
if (!group) {
return sendDeferredEphermeralResponse(interaction, {
content: `The group \`${groupName}\` does not exist.`,
});
}

// Get all the commands for the group
const commands = await getCommandsForGroup(
interaction.client,
interaction,
group.name
);

// Create a button for going back to the groups
const backButton = new ButtonBuilder() //
.setCustomId(GroupButtonIDs.BackToGroup)
.setEmoji(":back:")
.setStyle(ButtonStyle.Primary);

// Add the button to a action row
const row = new ActionRowBuilder<ButtonBuilder>();
row.addComponents(backButton);

// Embed builder
const embed = new EmbedBuilder() //
.setColor(0x2095ab)
.setAuthor({
name: interaction.user.username,
iconURL: interaction.user.displayAvatarURL(),
})
.addFields([
{
name: "Information",
value: `Click on the 🔙 button to go back to the groups.`,
},
{
name: `${group.name} Commands`,
value:
commands
.map(
(command) =>
`\`/${command.name}\` ${command.description}`
)
.join("\n") || "No commands found",
},
]);

return sendDeferredResponse(interaction, {
embeds: [embed],
components: [row],
});
}
export async function replyWithCommands(
interaction: ChatInputCommandInteraction | MessageComponentInteraction,
groupName: string
) {
await autoDeferReply(interaction);

// Check the group exists
const group = await getGroup(interaction.client, interaction, groupName);
if (!group) {
return sendDeferredEphermeralResponse(interaction, {
content: `The group \`${groupName}\` does not exist.`,
});
}

// Get all the commands for the group
const commands = await getCommandsForGroup(
interaction.client,
interaction,
group.name
);

// Create a button for going back to the groups
const backButton = new ButtonBuilder() //
.setCustomId(GroupButtonIDs.BackToGroup)
.setEmoji(":back:")
.setStyle(ButtonStyle.Primary);

// Add the button to a action row
const row = new ActionRowBuilder<ButtonBuilder>();
row.addComponents(backButton);

// Embed builder
const embed = new EmbedBuilder() //
.setColor(0x2095ab)
.setAuthor({
name: interaction.user.username,
iconURL: interaction.user.displayAvatarURL(),
})
.addFields([
{
name: "Information",
value: `Click on the 🔙 button to go back to the groups.`,
},
{
name: `${group.name} Commands`,
value:
commands
.map(
(command) =>
`\`/${command.name}\` ${command.description}`
)
.join("\n") || "No commands found",
},
]);

return sendDeferredResponse(interaction, {
embeds: [embed],
components: [row],
});
}
interactionReplyUtil General utils for interactions
/**
* This util will defer the reply only when it is able to.
*
* @param interaction
*/
export async function autoDeferReply(
interaction: ChatInputCommandInteraction | MessageComponentInteraction
) {
const fromMessageComponent = isMessageComponentInteraction(interaction);
// Defer the interaction if it hasn't already been (command interaction)
if (
!fromMessageComponent &&
!interaction.deferred &&
!interaction.replied
) {
await interaction.deferReply();
}
}

export async function sendDeferredResponse(
interaction: ChatInputCommandInteraction | MessageComponentInteraction,
options?: BaseMessageOptions
): Promise<InteractionResponse<boolean> | Message<boolean>> {
const { content, embeds, components } = options ?? {};
// Response to the interaction
const responseObj: BaseMessageOptions = {
content: content ?? "",
embeds,
components,
};
const fromMessageComponent = isMessageComponentInteraction(interaction);
// A button interaction cause this function to be called
if (fromMessageComponent && !interaction.replied) {
return interaction.update(responseObj);
}
// A command interaction cause this function to be called
return interaction.editReply(responseObj);
}
/**
* This util will defer the reply only when it is able to.
*
* @param interaction
*/
export async function autoDeferReply(
interaction: ChatInputCommandInteraction | MessageComponentInteraction
) {
const fromMessageComponent = isMessageComponentInteraction(interaction);
// Defer the interaction if it hasn't already been (command interaction)
if (
!fromMessageComponent &&
!interaction.deferred &&
!interaction.replied
) {
await interaction.deferReply();
}
}

export async function sendDeferredResponse(
interaction: ChatInputCommandInteraction | MessageComponentInteraction,
options?: BaseMessageOptions
): Promise<InteractionResponse<boolean> | Message<boolean>> {
const { content, embeds, components } = options ?? {};
// Response to the interaction
const responseObj: BaseMessageOptions = {
content: content ?? "",
embeds,
components,
};
const fromMessageComponent = isMessageComponentInteraction(interaction);
// A button interaction cause this function to be called
if (fromMessageComponent && !interaction.replied) {
return interaction.update(responseObj);
}
// A command interaction cause this function to be called
return interaction.editReply(responseObj);
}
2 Replies
Duck
Duck•4mo ago
"discord.js": "^14.14.1",
2023-12-16 12:23:43 - ERROR - Encountered error while handling an interaction handler run method for interaction-handler "GroupButton" at path "C:\Users\askme\Desktop\testing-forbidden\dist\interaction-handlers\help\GroupButton.js" DiscordAPIError[10062]: Unknown interaction
2023-12-16 12:23:43 - ERROR - at handleErrors (C:\Users\askme\Desktop\testing-forbidden\node_modules\@discordjs\rest\dist\index.js:722:13)
2023-12-16 12:23:43 - ERROR - at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2023-12-16 12:23:43 - ERROR - at async BurstHandler.runRequest (C:\Users\askme\Desktop\testing-forbidden\node_modules\@discordjs\rest\dist\index.js:826:23)
2023-12-16 12:23:43 - ERROR - at async _REST.request (C:\Users\askme\Desktop\testing-forbidden\node_modules\@discordjs\rest\dist\index.js:1266:22)
2023-12-16 12:23:43 - ERROR - at async ButtonInteraction.reply (C:\Users\askme\Desktop\testing-forbidden\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:111:5)
2023-12-16 12:23:43 - ERROR - at async Object.fromAsync (C:\Users\askme\Desktop\testing-forbidden\node_modules\@sapphire\result\dist\index.js:613:22)
2023-12-16 12:23:43 - ERROR - at async Promise.allSettled (index 0)
2023-12-16 12:23:43 - ERROR - at async _InteractionHandlerStore.run (C:\Users\askme\Desktop\testing-forbidden\node_modules\@sapphire\framework\dist\lib\structures\InteractionHandlerStore.js:48:21)
2023-12-16 12:23:43 - ERROR - at async _CoreListener.run (C:\Users\askme\Desktop\testing-forbidden\node_modules\@sapphire\framework\dist\listeners\CoreInteractionCreate.js:21:7)
2023-12-16 12:23:43 - ERROR - at async Object.fromAsync (C:\Users\askme\Desktop\testing-forbidden\node_modules\@sapphire\result\dist\index.js:613:22) {
2023-12-16 12:23:43 - ERROR - requestBody: [Object],
2023-12-16 12:23:43 - ERROR - rawError: [Object],
2023-12-16 12:23:43 - ERROR - code: 10062,
2023-12-16 12:23:43 - ERROR - status: 404,
2023-12-16 12:23:43 - ERROR - method: 'POST',
2023-12-16 12:23:43 - ERROR - url: 'https://discord.com/api/v10/interactions/1185406840272588810/aW50ZXJhY3Rpb246MTE4NTQwNjg0MDI3MjU4ODgxMDpNSWNFaFZUc1l4YlNRd3dCa1g2UVRtRDZGWGNFV3d5d25nZFl5QXVyUU5yQnFnZ21CQ2N3bk8xWDlncTBQU1FORnl1eEtPcHJzaFM2bUVWQk1MNXZmNEU5eFVMeW9ScmJBZnBESWdGTGhRbmJHNnhZTVBUc3JnNW8zbmp0WVFiRA/callback'
2023-12-16 12:23:43 - ERROR - }
2023-12-16 12:23:43 - ERROR - Encountered error while handling an interaction handler run method for interaction-handler "GroupButton" at path "C:\Users\askme\Desktop\testing-forbidden\dist\interaction-handlers\help\GroupButton.js" DiscordAPIError[10062]: Unknown interaction
2023-12-16 12:23:43 - ERROR - at handleErrors (C:\Users\askme\Desktop\testing-forbidden\node_modules\@discordjs\rest\dist\index.js:722:13)
2023-12-16 12:23:43 - ERROR - at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2023-12-16 12:23:43 - ERROR - at async BurstHandler.runRequest (C:\Users\askme\Desktop\testing-forbidden\node_modules\@discordjs\rest\dist\index.js:826:23)
2023-12-16 12:23:43 - ERROR - at async _REST.request (C:\Users\askme\Desktop\testing-forbidden\node_modules\@discordjs\rest\dist\index.js:1266:22)
2023-12-16 12:23:43 - ERROR - at async ButtonInteraction.reply (C:\Users\askme\Desktop\testing-forbidden\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:111:5)
2023-12-16 12:23:43 - ERROR - at async Object.fromAsync (C:\Users\askme\Desktop\testing-forbidden\node_modules\@sapphire\result\dist\index.js:613:22)
2023-12-16 12:23:43 - ERROR - at async Promise.allSettled (index 0)
2023-12-16 12:23:43 - ERROR - at async _InteractionHandlerStore.run (C:\Users\askme\Desktop\testing-forbidden\node_modules\@sapphire\framework\dist\lib\structures\InteractionHandlerStore.js:48:21)
2023-12-16 12:23:43 - ERROR - at async _CoreListener.run (C:\Users\askme\Desktop\testing-forbidden\node_modules\@sapphire\framework\dist\listeners\CoreInteractionCreate.js:21:7)
2023-12-16 12:23:43 - ERROR - at async Object.fromAsync (C:\Users\askme\Desktop\testing-forbidden\node_modules\@sapphire\result\dist\index.js:613:22) {
2023-12-16 12:23:43 - ERROR - requestBody: [Object],
2023-12-16 12:23:43 - ERROR - rawError: [Object],
2023-12-16 12:23:43 - ERROR - code: 10062,
2023-12-16 12:23:43 - ERROR - status: 404,
2023-12-16 12:23:43 - ERROR - method: 'POST',
2023-12-16 12:23:43 - ERROR - url: 'https://discord.com/api/v10/interactions/1185406840272588810/aW50ZXJhY3Rpb246MTE4NTQwNjg0MDI3MjU4ODgxMDpNSWNFaFZUc1l4YlNRd3dCa1g2UVRtRDZGWGNFV3d5d25nZFl5QXVyUU5yQnFnZ21CQ2N3bk8xWDlncTBQU1FORnl1eEtPcHJzaFM2bUVWQk1MNXZmNEU5eFVMeW9ScmJBZnBESWdGTGhRbmJHNnhZTVBUc3JnNW8zbmp0WVFiRA/callback'
2023-12-16 12:23:43 - ERROR - }
And it is almost a direct copy of this which does work DuckRefreshButton.ts the button
public async run(interaction: ButtonInteraction) {
replyToInteraction(interaction);
}
public async run(interaction: ButtonInteraction) {
replyToInteraction(interaction);
}
replyToInteration.ts for the duck command
export async function replyToInteraction(
interaction: ChatInputCommandInteraction | MessageComponentInteraction
) {
await autoDeferReply(interaction);

// Buttons
const refreshButton = new ButtonBuilder() //
.setCustomId(duckRefreshButtonID)
.setLabel("New Duck")
.setStyle(ButtonStyle.Primary);

// Action builder
const row = new ActionRowBuilder<ButtonBuilder>() //
.addComponents(refreshButton);

// Embed builder
const embed = new EmbedBuilder() //
.setColor(0x2095ab)
.setAuthor({
name: interaction.user.username,
iconURL: interaction.user.displayAvatarURL(),
})
.setDescription("Oh look it's a Duck :DuckLove:");

// Retrieve the image
const duck = await fetchDuck(interaction, embed);
if (typeof duck === "string") {
embed.setImage(duck);
return sendDeferredResponse(interaction, {
embeds: [embed],
components: [row],
});
}
}
export async function replyToInteraction(
interaction: ChatInputCommandInteraction | MessageComponentInteraction
) {
await autoDeferReply(interaction);

// Buttons
const refreshButton = new ButtonBuilder() //
.setCustomId(duckRefreshButtonID)
.setLabel("New Duck")
.setStyle(ButtonStyle.Primary);

// Action builder
const row = new ActionRowBuilder<ButtonBuilder>() //
.addComponents(refreshButton);

// Embed builder
const embed = new EmbedBuilder() //
.setColor(0x2095ab)
.setAuthor({
name: interaction.user.username,
iconURL: interaction.user.displayAvatarURL(),
})
.setDescription("Oh look it's a Duck :DuckLove:");

// Retrieve the image
const duck = await fetchDuck(interaction, embed);
if (typeof duck === "string") {
embed.setImage(duck);
return sendDeferredResponse(interaction, {
embeds: [embed],
components: [row],
});
}
}
Still having this issue and haven't figured out why just yet I tried a more basic approach by having the button handle a specific interaction.
export class BasicButton extends InteractionHandler {
public group: Group | undefined;

public constructor(ctx: LoaderContext, options: InteractionHandlerOptions) {
super(ctx, {
...options,
id: "group_basic",
name: "BasicButton",
interactionHandlerType: InteractionHandlerTypes.Button,
});
}

public override async validate(interaction: ButtonInteraction) {
// Check the group exists
const group = await getGroup(interaction.client, interaction, "basic");
if (!group) return this.none();

// Store the group
this.group = group;
return this.some();
}

public run(interaction: ButtonInteraction) {
// If the group is undefined then we should not run
if (!this.group) return;

// We can now run the command
return interaction.reply("test");
// return replyWithCommands(interaction, this.group.name);
}
}
export class BasicButton extends InteractionHandler {
public group: Group | undefined;

public constructor(ctx: LoaderContext, options: InteractionHandlerOptions) {
super(ctx, {
...options,
id: "group_basic",
name: "BasicButton",
interactionHandlerType: InteractionHandlerTypes.Button,
});
}

public override async validate(interaction: ButtonInteraction) {
// Check the group exists
const group = await getGroup(interaction.client, interaction, "basic");
if (!group) return this.none();

// Store the group
this.group = group;
return this.some();
}

public run(interaction: ButtonInteraction) {
// If the group is undefined then we should not run
if (!this.group) return;

// We can now run the command
return interaction.reply("test");
// return replyWithCommands(interaction, this.group.name);
}
}
No luck, same error. For those unaware, I have a wrapper on interaction handler that allows me to run preconditions through interactions. Weirdly enough I know how to stop the error, my interaction handler that runs preconditions on the interaction is the reason it's erroring. It doesn't error on my other interactions only in this specific scenario. I don't know why it's causing an unknown interaction error, if anyone knows anything about this error or wants to help please hmu For whatever reason if I send a reply immediately in the parse function of sapphire's interaction handler before it's sent to mine, it stops the error. :BRUH:
Favna
Favna•4mo ago
You may want to review our docs on interaction handlers. The idea is that in parse you only define if the interaction handler should run for that particular interactionCreate event and maybe some preparing data (but do that after rejecting it for the incorrect interactionCreate!) and then send replies in run. https://sapphirejs.dev/docs/Guide/interaction-handlers/what-are-they Every interaction handler must have a parse and run method. As for how to send a reply from an interaction handler, if you want some examples look at the docs linked above, or take an example from another bot such as @Dragonite (https://github.com/favware/dragonite) Your code is a bit hard to follow along because of the various utility functions wrapping functionality so I can't really make rhyme or reason of a lot of it. Also you asked in this #discordjs-support but we also have #sapphire-support btw 🙂
Sapphire Framework
What are they? | Sapphire
These are interaction handlers! A simple class you can extend to handle almost all the interactions you may receive in
GitHub
GitHub - favware/dragonite: A Pokémon information Discord bot built...
A Pokémon information Discord bot built around Discord Interactions - favware/dragonite