crash when loading a autocomplete
The code show an error when I am trying to use a autocomplete in a command
import { InteractionHandler, InteractionHandlerTypes } from '@sapphire/framework';
import type { AutocompleteInteraction } from 'discord.js';
export class AutocompleteHandler extends InteractionHandler {
public constructor(ctx: InteractionHandler.LoaderContext, options: InteractionHandler.Options) {
super(ctx, {
...options,
interactionHandlerType: InteractionHandlerTypes.Autocomplete
});
}
public override async run(interaction: AutocompleteInteraction, result: InteractionHandler.ParseResult<this>) {
return interaction.respond(result);
}
public override async parse(interaction: AutocompleteInteraction) {
if (interaction.commandName !== 'panel') return this.none();
const focusedOption = interaction.options.getFocused(true);
switch (focusedOption.name) {
case 'panel': {
const searchResult = this.container.prisma.ticketPanel.findMany({
where: {
guildId: interaction.guildId!
}
});
// Map the search results to the structure required for Autocomplete
return this.some(
(await searchResult).map((panel) => ({
name: panel.title,
value: panel.id,
description: panel.description
}))
);
}
default:
return this.none();
}
}
}
import { InteractionHandler, InteractionHandlerTypes } from '@sapphire/framework';
import type { AutocompleteInteraction } from 'discord.js';
export class AutocompleteHandler extends InteractionHandler {
public constructor(ctx: InteractionHandler.LoaderContext, options: InteractionHandler.Options) {
super(ctx, {
...options,
interactionHandlerType: InteractionHandlerTypes.Autocomplete
});
}
public override async run(interaction: AutocompleteInteraction, result: InteractionHandler.ParseResult<this>) {
return interaction.respond(result);
}
public override async parse(interaction: AutocompleteInteraction) {
if (interaction.commandName !== 'panel') return this.none();
const focusedOption = interaction.options.getFocused(true);
switch (focusedOption.name) {
case 'panel': {
const searchResult = this.container.prisma.ticketPanel.findMany({
where: {
guildId: interaction.guildId!
}
});
// Map the search results to the structure required for Autocomplete
return this.some(
(await searchResult).map((panel) => ({
name: panel.title,
value: panel.id,
description: panel.description
}))
);
}
default:
return this.none();
}
}
}
10 Replies
2025-02-08 00:25:15 - ERROR - Encountered error while handling an interaction handler run method for interaction-handler "PanelAutoComplete" at path "E:\stereo-bot\dist\interaction-handlers\autocomplete\PanelAutoComplete.js" DiscordAPIError[10062]: Unknown interaction
2025-02-08 00:25:15 - ERROR - at handleErrors (E:\stereo-bot\node_modules\@discordjs\rest\dist\index.js:727:13)
2025-02-08 00:25:15 - ERROR - at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2025-02-08 00:25:15 - ERROR - at async BurstHandler.runRequest (E:\stereo-bot\node_modules\@discordjs\rest\dist\index.js:831:23)
2025-02-08 00:25:15 - ERROR - at async _REST.request (E:\stereo-bot\node_modules\@discordjs\rest\dist\index.js:1272:22)
2025-02-08 00:25:15 - ERROR - at async AutocompleteInteraction.respond (E:\stereo-bot\node_modules\discord.js\src\structures\AutocompleteInteraction.js:86:5)
2025-02-08 00:25:15 - ERROR - at async Result.fromAsync (E:\stereo-bot\node_modules\@sapphire\result\dist\cjs\index.cjs:957:22)
2025-02-08 00:25:15 - ERROR - at async Promise.allSettled (index 0)
2025-02-08 00:25:15 - ERROR - at async _InteractionHandlerStore.run (E:\stereo-bot\node_modules\@sapphire\framework\dist\cjs\lib\structures\InteractionHandlerStore.cjs:45:21)
2025-02-08 00:25:15 - ERROR - at async _CoreListener.run (E:\stereo-bot\node_modules\@sapphire\framework\dist\cjs\listeners\application-commands\CorePossibleAutocompleteInteraction.cjs:34:5)
2025-02-08 00:25:15 - ERROR - at async Result.fromAsync (E:\stereo-bot\node_modules\@sapphire\result\dist\cjs\index.cjs:957:22) {
2025-02-08 00:25:15 - ERROR - requestBody: [Object],
2025-02-08 00:25:15 - ERROR - rawError: [Object],
2025-02-08 00:25:15 - ERROR - code: 10062,
2025-02-08 00:25:15 - ERROR - status: 404,
2025-02-08 00:25:15 - ERROR - method: 'POST',
2025-02-08 00:25:15 - ERROR - url: 'https://discord.com/api/v10/interactions/1337565645365313556/aW50ZXJhY3Rpb246MTMzNzU2NTY0NTM2NTMxMzU1NjpwZE11VXBMZmRDQzU0elFxcnFmNG1vRWdGTVc1SVRGNVN2UlhCY09zaWhpUHp0QXRzQzNlQ2NObnF5a04wQnI0NXNOTVUySUJZc0lJN2wzRzZmcWs0NzdLNGR5eXVqVVNiS2JjUmIyc1JTeGdEcnQ4dlk1cWFxeWgwQjNUZkVHaw/callback'
2025-02-08 00:25:15 - ERROR - }
2025-02-08 00:25:15 - ERROR - Encountered error while handling an interaction handler run method for interaction-handler "PanelAutoComplete" at path "E:\stereo-bot\dist\interaction-handlers\autocomplete\PanelAutoComplete.js" DiscordAPIError[10062]: Unknown interaction
2025-02-08 00:25:15 - ERROR - at handleErrors (E:\stereo-bot\node_modules\@discordjs\rest\dist\index.js:727:13)
2025-02-08 00:25:15 - ERROR - at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2025-02-08 00:25:15 - ERROR - at async BurstHandler.runRequest (E:\stereo-bot\node_modules\@discordjs\rest\dist\index.js:831:23)
2025-02-08 00:25:15 - ERROR - at async _REST.request (E:\stereo-bot\node_modules\@discordjs\rest\dist\index.js:1272:22)
2025-02-08 00:25:15 - ERROR - at async AutocompleteInteraction.respond (E:\stereo-bot\node_modules\discord.js\src\structures\AutocompleteInteraction.js:86:5)
2025-02-08 00:25:15 - ERROR - at async Result.fromAsync (E:\stereo-bot\node_modules\@sapphire\result\dist\cjs\index.cjs:957:22)
2025-02-08 00:25:15 - ERROR - at async Promise.allSettled (index 0)
2025-02-08 00:25:15 - ERROR - at async _InteractionHandlerStore.run (E:\stereo-bot\node_modules\@sapphire\framework\dist\cjs\lib\structures\InteractionHandlerStore.cjs:45:21)
2025-02-08 00:25:15 - ERROR - at async _CoreListener.run (E:\stereo-bot\node_modules\@sapphire\framework\dist\cjs\listeners\application-commands\CorePossibleAutocompleteInteraction.cjs:34:5)
2025-02-08 00:25:15 - ERROR - at async Result.fromAsync (E:\stereo-bot\node_modules\@sapphire\result\dist\cjs\index.cjs:957:22) {
2025-02-08 00:25:15 - ERROR - requestBody: [Object],
2025-02-08 00:25:15 - ERROR - rawError: [Object],
2025-02-08 00:25:15 - ERROR - code: 10062,
2025-02-08 00:25:15 - ERROR - status: 404,
2025-02-08 00:25:15 - ERROR - method: 'POST',
2025-02-08 00:25:15 - ERROR - url: 'https://discord.com/api/v10/interactions/1337565645365313556/aW50ZXJhY3Rpb246MTMzNzU2NTY0NTM2NTMxMzU1NjpwZE11VXBMZmRDQzU0elFxcnFmNG1vRWdGTVc1SVRGNVN2UlhCY09zaWhpUHp0QXRzQzNlQ2NObnF5a04wQnI0NXNOTVUySUJZc0lJN2wzRzZmcWs0NzdLNGR5eXVqVVNiS2JjUmIyc1JTeGdEcnQ4dlk1cWFxeWgwQjNUZkVHaw/callback'
2025-02-08 00:25:15 - ERROR - }
the error says unknown interaction, you're probably not responding within 3 seconds, perhaps your query on ticketPanel is taking a while
Nah
It’s instant
She solution are showed instantly
But the error appear
I would defer the interaction regardless just to be sure. Especially because I see an await in there
The 3 seconds starts ticking the moment discord sends you the packet so by the time it has arrived on your system, you have processed it, sent it back and the packet has been received by discord, those 3 seconds may have very well passed.
You can't defer in autocomplete, Favna
So what can I do ?
the findMany can't be faster
it's literally instant
maybe it's just a discord moment since you did say the things do appear and perhaps your bot tried to handle an autocomplete interaction that you received after the interaction command had completed?
The interaction is buggued or maybe it’s my code the message is sent two times
Always sent two times when the error appear

I added a .then to the .send and I have only one log
So I don’t understand
This is the code
public async chatInputSend(interaction: Subcommand.ChatInputCommandInteraction) {
const panelId = interaction.options.getString('panel', true);
const channel = interaction.options.getChannel('salon', true) as TextChannel;
try {
// 1. Mettre à jour le channelId du panneau dans la base de données
await this.container.prisma.ticketPanel.update({
where: { id: panelId },
data: { channelId: channel.id }
});
// 2. Récupérer le panneau mis à jour
const panel = await this.container.prisma.ticketPanel.findUnique({
where: { id: panelId }
});
if (!panel) {
throw new Error(`Panel ${panelId} non trouvé`);
}
// 3. Récupérer le salon (targetChannel) où le panneau doit être envoyé
const targetChannel = (await interaction.guild!.channels.fetch(panel.channelId)) as TextChannel;
if (!targetChannel || !targetChannel.isTextBased()) {
throw new Error(`Channel ${panel.channelId} non trouvé ou n'est pas textuel`);
}
// 4. Créer l'embed du panneau
const ticketEmbed = new EmbedBuilder()
.setColor(Colors.Blurple)
.setTitle(panel.title)
.setDescription(panel.description || '')
.setFooter({ text: panel.footer || 'Ticket Diamond' });
// 5. Créer le bouton "Ouvrir un ticket"
const openTicketButton = new ButtonBuilder()
.setCustomId(`create-ticket-${panel.id}`)
.setLabel('Ouvrir un ticket')
.setStyle(ButtonStyle.Primary);
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(openTicketButton);
// 6. Supprimer l'ancien message du panneau s'il existe
if (panel.messageId) {
try {
const oldMessage = await targetChannel.messages.fetch(panel.messageId);
console.log(`Suppression de l'ancien message du panneau ${panel.messageId}`);
await oldMessage.delete();
} catch (error) {
// Erreur silencieuse : si la suppression échoue, l'ancien message reste
console.log(`Impossible de supprimer l'ancien message du panneau : ${error}`);
}
}
// 7. Envoyer le nouveau message du panneau
const newMessage = await targetChannel.send({
embeds: [ticketEmbed],
components: [row]
});
console.log(`Mise à jour du panneau ${panelId} avec le nouveau message ${newMessage.id}`);
// 8. Mettre à jour l'ID du message dans la base de données
await this.container.prisma.ticketPanel.update({
where: { id: panelId },
data: { messageId: newMessage.id }
});
// 9. Répondre à l'interaction avec un message de succès
const successEmbed = new EmbedBuilder()
.setColor(Colors.Green)
.setTitle('✅ Panneau envoyé avec succès')
.addFields(
{ name: 'Salon', value: `${channel}` },
{ name: 'ID du panneau', value: panel.id }
)
.setTimestamp();
await interaction.reply({
embeds: [successEmbed],
flags: MessageFlags.Ephemeral
});
} catch (error) {
console.error("Erreur lors de l'envoi du panneau :", error);
await interaction.reply({
content: `❌ Une erreur est survenue lors de l'envoi du panneau : ${error}`,
flags: MessageFlags.Ephemeral
});
}
}
public async chatInputSend(interaction: Subcommand.ChatInputCommandInteraction) {
const panelId = interaction.options.getString('panel', true);
const channel = interaction.options.getChannel('salon', true) as TextChannel;
try {
// 1. Mettre à jour le channelId du panneau dans la base de données
await this.container.prisma.ticketPanel.update({
where: { id: panelId },
data: { channelId: channel.id }
});
// 2. Récupérer le panneau mis à jour
const panel = await this.container.prisma.ticketPanel.findUnique({
where: { id: panelId }
});
if (!panel) {
throw new Error(`Panel ${panelId} non trouvé`);
}
// 3. Récupérer le salon (targetChannel) où le panneau doit être envoyé
const targetChannel = (await interaction.guild!.channels.fetch(panel.channelId)) as TextChannel;
if (!targetChannel || !targetChannel.isTextBased()) {
throw new Error(`Channel ${panel.channelId} non trouvé ou n'est pas textuel`);
}
// 4. Créer l'embed du panneau
const ticketEmbed = new EmbedBuilder()
.setColor(Colors.Blurple)
.setTitle(panel.title)
.setDescription(panel.description || '')
.setFooter({ text: panel.footer || 'Ticket Diamond' });
// 5. Créer le bouton "Ouvrir un ticket"
const openTicketButton = new ButtonBuilder()
.setCustomId(`create-ticket-${panel.id}`)
.setLabel('Ouvrir un ticket')
.setStyle(ButtonStyle.Primary);
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(openTicketButton);
// 6. Supprimer l'ancien message du panneau s'il existe
if (panel.messageId) {
try {
const oldMessage = await targetChannel.messages.fetch(panel.messageId);
console.log(`Suppression de l'ancien message du panneau ${panel.messageId}`);
await oldMessage.delete();
} catch (error) {
// Erreur silencieuse : si la suppression échoue, l'ancien message reste
console.log(`Impossible de supprimer l'ancien message du panneau : ${error}`);
}
}
// 7. Envoyer le nouveau message du panneau
const newMessage = await targetChannel.send({
embeds: [ticketEmbed],
components: [row]
});
console.log(`Mise à jour du panneau ${panelId} avec le nouveau message ${newMessage.id}`);
// 8. Mettre à jour l'ID du message dans la base de données
await this.container.prisma.ticketPanel.update({
where: { id: panelId },
data: { messageId: newMessage.id }
});
// 9. Répondre à l'interaction avec un message de succès
const successEmbed = new EmbedBuilder()
.setColor(Colors.Green)
.setTitle('✅ Panneau envoyé avec succès')
.addFields(
{ name: 'Salon', value: `${channel}` },
{ name: 'ID du panneau', value: panel.id }
)
.setTimestamp();
await interaction.reply({
embeds: [successEmbed],
flags: MessageFlags.Ephemeral
});
} catch (error) {
console.error("Erreur lors de l'envoi du panneau :", error);
await interaction.reply({
content: `❌ Une erreur est survenue lors de l'envoi du panneau : ${error}`,
flags: MessageFlags.Ephemeral
});
}
}