discordjs / discord.js

A powerful JavaScript library for interacting with the Discord API
https://discord.js.org
Apache License 2.0
25.25k stars 3.95k forks source link

Random "Unknown interaction" errors sometimes #7005

Closed ikheetjeff closed 2 years ago

ikheetjeff commented 2 years ago

Issue description

I have a bot with clicks on buttons every second and people executing commands. This generally goes very well, but sometimes I get an "Unknown Interaction" when I defer to it.

I've been debugging for the past three days and can't seem to understand why it's happening. My last possible explanation is an error in Discord.js or on the side of Discord.

I have attached a few screenshots describing the error Screenshot_17 Screenshot_18

I would prefer to know if this is due to my code, or Discord.js or Discord itself.

Code sample

// Button Handler
        if(interaction.isButton()) {
            console.log(customId);
            const button = client.buttons.get(customId);
            if(!button) return;

            let {
                cooldown = -1,
                deferUpdate = false
            } = button;

            if(deferUpdate) {
                console.error('defer button');
                const testHook = interaction;
                console.error(interaction.member.user.username, interaction.member.id)
                await interaction.deferUpdate();
                console.error("doei", interaction.member.user.username, interaction.member.id)

            }

            let buttonName = (customId.startsWith('games-all-')) ? "btn-games-all" : "btn-" + customId;
            console.log(buttonName);
            if(!cooldownButtons.has(buttonName)) {
                console.log(buttonName, 'add cooldown')
                cooldownButtons.set(buttonName, new Collection());
            }

            const currentBtnTime = Date.now();
            const timestamps = await cooldownButtons.get(buttonName);
            const cooldownAmount = (cooldown) * 1000;

            if(timestamps.has(member.id)) {
                console.log(member.id, 'heeft cooldown')
                const expirationTime = timestamps.get(member.id) + cooldownAmount;

                if(currentBtnTime < expirationTime) {
                    console.log(member.id, 'heeft cooldown')
                    const time_left = (expirationTime - currentBtnTime) / 1000;

                    if(deferUpdate) {
                        return interaction.followUp({content: `**Cooldown:** You have to wait ${time_left.toFixed(1)} seconds.`, ephemeral: true});
                    }else{
                        return interaction.followUp({content: `**Cooldown:** You have to wait ${time_left.toFixed(1)} seconds.`, ephemeral: true});
                    }
                }
            }else{
                timestamps.set(member.id, currentBtnTime);
                setTimeout(() => timestamps.delete(member.id), cooldownAmount);

                try{
                    await button.execute(interaction);
                }catch(error) {
                    console.error(error);
                }
            }
        }

discord.js version

13.3.1

Node.js version

16.13.0

Operating system

Debian 10

Priority this issue should have

Medium (should be fixed soon)

Which partials do you have configured?

CHANNEL, GUILD_MEMBER, MESSAGE, REACTION

Which gateway intents are you subscribing to?

GUILDS, GUILD_MEMBERS, GUILD_INVITES, GUILD_VOICE_STATES, GUILD_MESSAGES, GUILD_MESSAGE_REACTIONS, DIRECT_MESSAGES

I have tested this issue on a development release

No response

manuelvleeuwen commented 2 years ago

Could you provide a minimal, reproducible code sample?

ikheetjeff commented 2 years ago
index.js ```js // Events Handler const eventFiles = fs.readdirSync('./events').filter(file => file.endsWith('.js')); for (const file of eventFiles) { let event = require(`./events/${file}`); if(event.once) { client.once(event.name, async (...args) => await event.execute(...args)); }else{ client.on(event.name, async (...args) => { if(event.name == "interactionCreate") console.error(event.name, 'called event!'); event.execute(client, ...args); }); } } ```
interactionCreate ```js const {creator} = require('../config.json'); const wait = require('util').promisify(setTimeout); const { MessageEmbed, MessageActionRow, MessageButton, Collection } = require('discord.js'); let moment = require('moment'); let guildInfo = require('../app/modules/guildInfo.js'); let helper = require('../app/functions/helper.js'); let cooldownCommands = new Collection(); let cooldownButtons = new Collection(); let cooldownMenus = new Collection(); module.exports = { name: "interactionCreate", async execute(client, interaction) { console.error('interaction started!', interaction.member.id) let {message, member, channel, guild, commandName, customId} = interaction; if(channel.type == "DM") return interaction.reply({ content: 'Can\'t use commands here.', ephemeral: true}); // Select Menu Handler if(interaction.isSelectMenu()) { console.log(customId); const menu = client.menus.get(customId); if(!menu) return console.log('menu not found'); let { cooldown = -1, cooldownType = 1, deferReply = false, ephemeral = false, } = menu; if(deferReply) { console.error("defer menu") console.error(interaction.member.user.username, interaction.member.id) await interaction.deferUpdate({ ephemeral: ephemeral }); console.error("doei", interaction.member.user.username, interaction.member.id) } let selectName = (cooldownType === 2 && interaction.values.length === 1) ? "slc-value-" + interaction.values[0] : "slc-" + customId; if(!cooldownMenus.has(selectName)) { cooldownMenus.set(selectName, new Collection()); } const currentSelectTime = Date.now(); const timestamps = cooldownMenus.get(selectName); const cooldownAmount = (cooldown) * 1000; await interaction.message.edit({components: interaction.message.components}).catch((err) => {}); if(timestamps.has(member.id)) { const expirationTime = timestamps.get(member.id) + cooldownAmount; if(currentSelectTime < expirationTime) { const time_left = (expirationTime - currentSelectTime) / 1000; if(deferReply) return interaction.editReply({ content: `**Cooldown:** You have to wait ${time_left.toFixed(1)} seconds.`, ephemeral: true}); return interaction.reply({ content: `**Cooldown:** You have to wait ${time_left.toFixed(1)} seconds.`, ephemeral: true}); } } timestamps.set(member.id, currentSelectTime); setTimeout(() => timestamps.delete(member.id), cooldownAmount); try{ await menu.execute(interaction); }catch(error) { console.error(error); } } // Button Handler if(interaction.isButton()) { console.log(customId); const button = client.buttons.get(customId); if(!button) return; let { cooldown = -1, deferUpdate = false } = button; if(deferUpdate) { console.error('defer button'); const testHook = interaction; console.error(interaction.member.user.username, interaction.member.id) await interaction.deferUpdate(); console.error("doei", interaction.member.user.username, interaction.member.id) } let buttonName = (customId.startsWith('games-all-')) ? "btn-games-all" : "btn-" + customId; console.log(buttonName); if(!cooldownButtons.has(buttonName)) { console.log(buttonName, 'add cooldown') cooldownButtons.set(buttonName, new Collection()); } const currentBtnTime = Date.now(); const timestamps = await cooldownButtons.get(buttonName); const cooldownAmount = (cooldown) * 1000; if(timestamps.has(member.id)) { console.log(member.id, 'heeft cooldown') const expirationTime = timestamps.get(member.id) + cooldownAmount; if(currentBtnTime < expirationTime) { console.log(member.id, 'heeft cooldown TEEEEEEEEST') const time_left = (expirationTime - currentBtnTime) / 1000; if(deferUpdate) { return interaction.followUp({content: `**Cooldown:** You have to wait ${time_left.toFixed(1)} seconds.`, ephemeral: true}); }else{ return interaction.followUp({content: `**Cooldown:** You have to wait ${time_left.toFixed(1)} seconds.`, ephemeral: true}); } } }else{ timestamps.set(member.id, currentBtnTime); setTimeout(() => timestamps.delete(member.id), cooldownAmount); try{ await button.execute(interaction); }catch(error) { console.error(error); } } } // Command Handler if(interaction.isCommand()) { let command = interaction.client.commands.get(interaction.commandName); if(!command) return; let { data = null, maintenance = false, deferReply = false } = command; if(deferReply) { console.error('defer command'); console.error(interaction.member.user.username, interaction.member.id) await interaction.deferReply(); console.error("doei", interaction.member.user.username, interaction.member.id) } // Cooldown let cooldown = await guildInfo.cmdCooldown(guild, commandName).catch(console.error); cooldown = (cooldown == undefined) ? -1 : cooldown; //AllowedChannels let allowedChannels = await guildInfo.cmdAllowedChannels(guild, commandName).catch(console.error); //DeniedChannels let deniedChannels = await guildInfo.cmdDeniedChannels(guild, commandName).catch(console.error); // let deniedChannels= []; // let allowedChannels = []; // let cooldown = -1; if(allowedChannels.length) { if(typeof allowedChannels === "string") { allowedChannels = [allowedChannels] } } if(deniedChannels.length) { if(typeof deniedChannels === "string") { deniedChannels = [deniedChannels] } } if(maintenance && member.id !== creator['id']) return interaction.reply({content: 'This command is disabled.', ephemeral: true}); if(!allowedChannels.some(r=> r.includes(interaction.channel.id)) && allowedChannels.length && !member.permissions.has('ADMINISTRATOR')) return interaction.reply({content: 'You may not use this here.', ephemeral: true}); if(deniedChannels.some(r=> r.includes(interaction.channel.id)) && !member.permissions.has('ADMINISTRATOR')) return interaction.reply({content: 'You may not use this here.', ephemeral: true}); try{ if(!cooldownCommands.has(commandName)) { cooldownCommands.set(commandName, new Collection()); } const currentTime = Date.now(); const timestamps = cooldownCommands.get(commandName); const cooldownAmount = (cooldown) * 1000; if(timestamps.has(member.id)) { const expirationTime = timestamps.get(member.id) + cooldownAmount; if(currentTime < expirationTime) { const time_left = (expirationTime - currentTime) / 1000; if(deferReply) { return interaction.editReply({content: `**Cooldown:** You have to wait ${time_left.toFixed(1)} seconds.`, ephemeral: true}); }else{ return interaction.reply({content: `**Cooldown:** You have to wait ${time_left.toFixed(1)} seconds.`, ephemeral: true}); } } } timestamps.set(member.id, currentTime); setTimeout(() => timestamps.delete(member.id), cooldownAmount); const embed = new MessageEmbed() .setColor('#ED8223') .setDescription('👷 Deze command heb je in onderhoud-modus uitgevoerd.'); if(maintenance && member.id === creator['id']) await interaction.channel.send({embeds: [embed], ephemeral: true}); // Command uitvoert await command.execute(interaction); }catch(error) { console.error(error); if(deferReply) { await interaction.editReply({content: 'Something went wrong during execution.', ephemeral: true}); }else{ await interaction.reply({content: 'Something went wrong during execution.', ephemeral: true}); } } } }, } ```
/buttons/rules-confirm.js (see screenshot under the code) ```js const { MessageEmbed, MessageActionRow, MessageButton, Permissions } = require('discord.js'); let guildInfo = require('../app/modules/guildInfo.js'); const con = require(`../app/functions/db`); let invites = require('../app/modules/invites.js'); module.exports = { name: "rules-confirm", cooldown: 60, deferUpdate: true, async execute(interaction) { let { guild, member, channel} = interaction; try{ let community = await guildInfo.roles(guild, "community").catch(console.error); if(community) { await member.roles.add(community).catch((err) => channel.send(`Oops! I can't give ${member.toString()} a role! <@300319943793311744> ${err}`)); await invites.verify(interaction); } }catch(err) { console.error(err); } } } ``` ![Screenshot_19](https://user-images.githubusercontent.com/76551334/142645329-0446fda4-94a0-461b-9689-4f00e5e11189.png)

It happens most often when deferring this button. But sometimes it happens to a command. It can really go well for a few hours, and then get a bunch of errors in a row.

The bot is in a very busy server with multiple clicks every second. So if you want to test something in that server or want to watch it, you can. Please feel free to let me know what I can do for you.

imranbarbhuiya commented 2 years ago

Same happening for me. Its showing interaction failed to the user and throwing error of Unknown interaction. I tried with deferring before responding, but it's then showing the interaction isn't deferred or replied even when I deferred also in discord it's showing bot is thinking still I'm getting this error.

DTrombett commented 2 years ago

You need to await your defer

imranbarbhuiya commented 2 years ago

Oh sorry, my bad. Thank you.

philipaarseth commented 2 years ago

Same thing happened to me. Suddenly getting errors (though everything was working fine still).

It's not the 3 second rule, I checked and responses was always <1s.

According to the discord.js guide, deferring is something you'd use if you expect 3+ sec answers, but I tried it anyway and no more errors 🤷🏼‍♂️.

ikheetjeff commented 2 years ago

The point is: I get an Unknown Interaction very often when I want to defer an interaction (<2 seconds). I even upgraded my server and checked my firewall to see if there is anything with connections. But it remains.

24-11 02:33:07.360: 906848354590400563 aW50ZXJhY3Rpb246OTEyODc4NDU0NzcxNDMzNDgyOnJtZ0FPUEJhaEttdjF6dUJ2TDllRkNWMkpGZmpZNFAyT0sxOTBGREVXQ1lrT2d0S3Y2T0F0cEVVQWtzOTB0cjhxZ2pWR2JtcjJKY1JNTUtJRVgwdTBNWGswclR6dW5LSElRd0o5RnoxTGlKdG8wdHFHbXZsMmlDM1FrS3MwcmlV
24-11 02:33:07.859: DiscordAPIError: Unknown interaction
24-11 02:33:07.859:     at RequestHandler.execute (/home/discord/Bull/node_modules/discord.js/src/rest/RequestHandler.js:349:13)
24-11 02:33:07.859:     at runMicrotasks (<anonymous>)
24-11 02:33:07.859:     at processTicksAndRejections (node:internal/process/task_queues:96:5)
24-11 02:33:07.859:     at async RequestHandler.push (/home/discord/Bull/node_modules/discord.js/src/rest/RequestHandler.js:50:14)
24-11 02:33:07.859:     at async ButtonInteraction.reply (/home/discord/Bull/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:98:5)
24-11 02:33:07.859:     at async Object.execute (/home/discord/Bull/buttons/rules-confirm.js:21:17)
24-11 02:33:07.859:     at async Object.execute (/home/discord/Bull/events/interactionCreate.js:121:21) {
24-11 02:33:07.859:   method: 'post',
24-11 02:33:07.859:   path: '/interactions/912878454771433482/aW50ZXJhY3Rpb246OTEyODc4NDU0NzcxNDMzNDgyOnJtZ0FPUEJhaEttdjF6dUJ2TDllRkNWMkpGZmpZNFAyT0sxOTBGREVXQ1lrT2d0S3Y2T0F0cEVVQWtzOTB0cjhxZ2pWR2JtcjJKY1JNTUtJRVgwdTBNWGswclR6dW5LSElRd0o5RnoxTGlKdG8wdHFHbXZsMmlDM1FrS3MwcmlV/callback',
24-11 02:33:07.859:   code: 10062,
24-11 02:33:07.859:   httpStatus: 404,
24-11 02:33:07.859:   requestData: { json: { type: 4, data: [Object] }, files: [] }
24-11 02:33:07.859: }

Or:

24-11 02:35:27.329: 900609711169208322 aW50ZXJhY3Rpb246OTEyODc5MDU1MDQ3NjIyNjg2OllTc09wT21ObUVsSERuV244TTNFMUZIaExGUVVLdzBqSmpmQlBybDJTZlFtd0J0cG5JV21QZWd4TG9qcDZxMmVsYUFjN215VG5Jd3g4QUxwc3RWcDRoSlNnRzIxaXcxdzZDN0d3UEtCVlpJYW9IRTNvdFNtRlVYemFGa0JoM0pF
24-11 02:35:27.330: defer command invites
24-11 02:35:27.330: Spodermannnnn 900609711169208322
24-11 02:35:30.635: 912278128007720982 aW50ZXJhY3Rpb246OTEyODc5MDY4ODU5NDk4NTE2OmRDVjhzYW9oQmZ3cFJlVFI4ajNxQTM2TEdvTTJNRThmMlNtT0p1bWxBUnA3ZWRZdmVGd0JmZHZ1THlqY2pWdnI4QVFkaUVqUWsxMkl0U1pCNGRkMGFBMktKYnBOZ2R5UmxveEdidFphZVlma3Y4T2RQcGt6bmNEWVFyaWxqcTEz
24-11 02:35:32.985: 905646164202901565 aW50ZXJhY3Rpb246OTEyODc5MDc4Mzk3MzE3MTQxOkh0UWpJUE5GcTViQkRzSXFJVjAwenZHelY2Unc1ZXYwdTExUWpqeGJidGJ5Y215T2piQ2Z0S3RGMEpacFBHeDh1aXNsT2NBNjRHR2pJTllSRGg5Nk1QczRBV1ZadE00SmJET3RLY3NvakUxbFRpUTk4dnFDOW54OHN3TEdBMlBv
24-11 02:35:37.804: DiscordAPIError: Unknown interaction
24-11 02:35:37.804:     at RequestHandler.execute (/home/discord/Bull/node_modules/discord.js/src/rest/RequestHandler.js:349:13)
24-11 02:35:37.804:     at runMicrotasks (<anonymous>)
24-11 02:35:37.804:     at processTicksAndRejections (node:internal/process/task_queues:96:5)
24-11 02:35:37.804:     at async RequestHandler.push (/home/discord/Bull/node_modules/discord.js/src/rest/RequestHandler.js:50:14)
24-11 02:35:37.804:     at async CommandInteraction.deferReply (/home/discord/Bull/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:57:5)
24-11 02:35:37.804:     at async Object.execute (/home/discord/Bull/events/interactionCreate.js:143:17) {
24-11 02:35:37.804:   method: 'post',
24-11 02:35:37.804:   path: '/interactions/912879055047622686/aW50ZXJhY3Rpb246OTEyODc5MDU1MDQ3NjIyNjg2OllTc09wT21ObUVsSERuV244TTNFMUZIaExGUVVLdzBqSmpmQlBybDJTZlFtd0J0cG5JV21QZWd4TG9qcDZxMmVsYUFjN215VG5Jd3g4QUxwc3RWcDRoSlNnRzIxaXcxdzZDN0d3UEtCVlpJYW9IRTNvdFNtRlVYemFGa0JoM0pF/callback',
24-11 02:35:37.804:   code: 10062,
24-11 02:35:37.804:   httpStatus: 404,
24-11 02:35:37.804:   requestData: { json: { type: 5, data: [Object] }, files: [] }
24-11 02:35:37.804: }
Jiralite commented 2 years ago

I'd like to voice that I'm not hitting these issues at all. My slash commands utilise both deferring and not deferring on 13.3.1. If this is an actual issue, I would have thought this would have more activity, right? This is a very core concept.

By the way, a minimal reproduction sample doesn't mean copying and pasting your entire file. A minimal reproduction sample means supplying the bare minimum code that you can reproduce the issue with. For example:

const { Client } = require("discord.js");

const client = new Client({
  intents: []
});

client.once("ready", async () => {
  // Create the command
  client.application.commands.create({
    name: "test",
    description: "test"
  }, "guild_id");
});

client.on("interactionCreate", async interaction => {
  await interaction.deferReply();
  interaction.editReply("Hello!");
});

client.login("token");

This seems to be the basis of your issue where sometimes awaiting the .deferReply() would error. I have spammed this command to no avail so I'm not able to reproduce this in testing or production. I'm not sure how to remedy this for you other than suggest it may be your own code?

ikheetjeff commented 2 years ago

This seems to be the basis of your issue where sometimes awaiting the .deferReply() would error. I have spammed this command to no avail so I'm not able to reproduce this in testing or production. I'm not sure how to remedy this for you other than suggest it may be your own code?

Thank you for your response and thoughtfulness. I currently have 6 different bots on my linux server. All bots are used sometimes, but the bot where I have this issue is used every second. Then again it is very random when this happens. Sometimes it doesn't happen for a while, sometimes a few times in a row.

I don't have it with all my other bots with the same code. Just because it is so unexpected, I wanted to send exactly my code to possibly see where the issue might be.

I'm trying to ask big bots that use buttons as well, but haven't gotten a response to this yet. I'd just like to know if it's because of me or Discord.

Should anyone want to watch live with me via screen share via Discord, they can. Then you can also see the problem immediately. @Jiralite @thehackerboi69github

applebee1558 commented 2 years ago

Does your Linux server by any chance have its cpu a bit overloaded with all the bots that it isn’t able to quickly decode every payload and send a request in time?

In addition, are you frequently changing the status of your bot? It’s more noticeable with bigger bots as the gateway delays all events until it publishes your presence to every guild.

ikheetjeff commented 2 years ago

Does your Linux server by any chance have its cpu a bit overloaded with all the bots that it isn’t able to quickly decode every payload and send a request in time?

In addition, are you frequently changing the status of your bot? It’s more noticeable with bigger bots as the gateway delays all events until it publishes your presence to every guild.

I don't update my status of my bot, except the activity I update every day.

I also doubt if it is due to the server. That's why I increased it in capacity. No difference yet. I'm going to try another hosting now, see if that makes a difference.

suneettipirneni commented 2 years ago

Hi, if there's not enough convincing evidence that this is a bug with discord.js I would recommend converting this issue into a discussion.

ikheetjeff commented 2 years ago

Hi, if there's not enough convincing evidence that this is a bug with discord.js I would recommend converting this issue into a discussion.

I have the bot on a new server for about 10 minutes now and have no problems. I don't want to get ahead of myself and take a few hours to see what happens. I would like to wait this out if that is okay.

ikheetjeff commented 2 years ago
25-11 05:01:53.628: event started 897553860535681075 xxtim aW50ZXJhY3Rpb246OTEzMjc4MjUxNzA5OTExMTAyOnpLU25mdW82NEhDRDRwYXNpbTBxdFowR3psU3RoOGROWHVDT3h0WDRXMTNIS2dhSUt2V2xtcVF6VDVsT0czWXZFcmRWS29ONFY5WHVhWDFaSjFIREs2QTkxTlVWTVpuQ1ZvSTNWU2I5N2hGRnAyenRzNnZKdmVPSHI1NElQN2di
25-11 05:01:53.628: first line module 897553860535681075 aW50ZXJhY3Rpb246OTEzMjc4MjUxNzA5OTExMTAyOnpLU25mdW82NEhDRDRwYXNpbTBxdFowR3psU3RoOGROWHVDT3h0WDRXMTNIS2dhSUt2V2xtcVF6VDVsT0czWXZFcmRWS29ONFY5WHVhWDFaSjFIREs2QTkxTlVWTVpuQ1ZvSTNWU2I5N2hGRnAyenRzNnZKdmVPSHI1NElQN2di
25-11 05:01:53.628: defer button
25-11 05:01:53.628: xxtim 897553860535681075
25-11 05:01:53.924: DiscordAPIError: Unknown interaction
25-11 05:01:53.924:     at RequestHandler.execute (/home/bull/bull-bot/node_modules/discord.js/src/rest/RequestHandler.js:349:13)
25-11 05:01:53.924:     at runMicrotasks (<anonymous>)
25-11 05:01:53.924:     at processTicksAndRejections (node:internal/process/task_queues:96:5)
25-11 05:01:53.924:     at async RequestHandler.push (/home/bull/bull-bot/node_modules/discord.js/src/rest/RequestHandler.js:50:14)
25-11 05:01:53.924:     at async ButtonInteraction.deferReply (/home/bull/bull-bot/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:57:5)
25-11 05:01:53.924:     at async Object.execute (/home/bull/bull-bot/events/interactionCreate.js:86:17) {
25-11 05:01:53.924:   method: 'post',
25-11 05:01:53.924:   path: '/interactions/913278251709911102/aW50ZXJhY3Rpb246OTEzMjc4MjUxNzA5OTExMTAyOnpLU25mdW82NEhDRDRwYXNpbTBxdFowR3psU3RoOGROWHVDT3h0WDRXMTNIS2dhSUt2V2xtcVF6VDVsT0czWXZFcmRWS29ONFY5WHVhWDFaSjFIREs2QTkxTlVWTVpuQ1ZvSTNWU2I5N2hGRnAyenRzNnZKdmVPSHI1NElQN2di/callback',
25-11 05:01:53.924:   code: 10062,
25-11 05:01:53.924:   httpStatus: 404,
25-11 05:01:53.924:   requestData: { json: { type: 5, data: [Object] }, files: [] }
25-11 05:01:53.924: }

I finally figured out what is actually the problem. It has nothing to do with my server, even then I get errors. If I only convert the snowflake of the interaction to a time, I see that my event is only called far too late. See above the time it is called.

If I convert the snowflake, I end up with: 25-11-2021 05:01:43

I just don't know now if Discord is sending this to me too late, or if Discord.js is processing this too late. Anyone know / can look into this?

philipaarseth commented 2 years ago

I found out much later that the reason why I was getting these problems was the fact that I was running my bot locally when I was testing in addition to in production on Heroku (turns out maintenance mode "offline" doesn't really mean shutting down the bot). Which meant that the Heroku bot would catch the interactions first and my local bot would give errors.

ChrisTalman commented 2 years ago

I just don't know now if Discord is sending this to me too late, or if Discord.js is processing this too late. Anyone know / can look into this?

I had this problem when I was manually calling the Discord API, prior to upgrading to discord.js@13.0.0.

I kinda get the feeling that 3 seconds is simply too little time for applications to respond within, hence why these errors appear every now and then.

I've tried to implement things like immediate deferral or a timeout for deferral, and yet a few of these errors still occur.

It has also crossed my mind whether there might be differences between the clock of my server and the clock of Discord's servers, which could make it difficult to work out when an interaction is still valid, or whether it's too late to respond.

coder-lcn commented 2 years ago

I also encountered the same problem. I tried the delay method in "https://discordjs.guide/interactions/replying-to-slash-commands.html#deferred-responses" and it worked. But when the number of concurrent clicks of the button is about 30 times, it is normal. But once the number of concurrent clicks reaches several hundred, it still reports this error.

ChrisTalman commented 2 years ago

Interesting, @LiChangNan-Programmer.

I wonder whether that's because of rate limits. As I understand it, discord.js will queue API requests when appropriate to avoid hitting rate limits. If the queue is long enough, an interaction response request might only be sent after the 3 second initial response window has passed, producing an API error.

xhyrom commented 2 years ago

I can confirm that this happens to me very often with autocomplete.

require('dotenv').config();
const { Client } = require('discord.js');
const { search } = require("youtube-sr").default;

const client = new Client({
    intents: ['GUILDS']
})

client.on('ready', async() => {
    console.log('ready');
});

client.on('interactionCreate', async(interaction) => {
    if(interaction.isAutocomplete()) {
        let query = interaction.options.getString('query', true);
        if(query.length == 0) query = 'Never gonna give you up';

        const videos = await search(query, { limit: 25 });

        interaction.respond(videos.map(video => {
            return {
                name: video.title,
                value: video.url
            }
        }))
    }
})
advaith1 commented 2 years ago

your youtube search is probably taking over 3s to complete and respond

coder-lcn commented 2 years ago

@ChrisTalman

I agree with you, but the frustrating thing is that I can't find documentation on this. The users in the community where I work are crazy, and the operation frequency is too high, and they often complain to me about the failure of the interaction, and I can't do anything. In addition, I think it is necessary to have a message queue, but the button should not give the wrong response.

ikheetjeff commented 2 years ago

My output with apiResponse event:

30-12 05:54:26.624: ApiRequest: {
30-12 05:54:26.624:   method: 'post',
30-12 05:54:26.624:   path: '/interactions/925975082281603083/aW50ZXJhY3Rpb246OTI1OTc1MDgyMjgxNjAzMDgzOmJ6dkx4OG5zMXV0TmlPUUI1UmZ1S1RHNTdobzVRYkZ6MjNRYVlzOVI3Z1o4N2hmVWF4bGJDNW1jalNWaVlkTjhYUWdFVVBqZkNSR25qYW1sQnhxRVdVRFBscklhYWFQcUlCTnpvSkNlaElsb0JwcklGQW1xR0xhcDB6NVJKdEx5/callback',
30-12 05:54:26.624:   route: '/interactions/:id/aW50ZXJhY3Rpb246OTI1OTc1MDgyMjgxNjAzMDgzOmJ6dkx4OG5zMXV0TmlPUUI1UmZ1S1RHNTdobzVRYkZ6MjNRYVlzOVI3Z1o4N2hmVWF4bGJDNW1jalNWaVlkTjhYUWdFVVBqZkNSR25qYW1sQnhxRVdVRFBscklhYWFQcUlCTnpvSkNlaElsb0JwcklGQW1xR0xhcDB6NVJKdEx5/callback',
30-12 05:54:26.624:   options: {
30-12 05:54:26.624:     versioned: true,
30-12 05:54:26.624:     route: '/interactions/:id/aW50ZXJhY3Rpb246OTI1OTc1MDgyMjgxNjAzMDgzOmJ6dkx4OG5zMXV0TmlPUUI1UmZ1S1RHNTdobzVRYkZ6MjNRYVlzOVI3Z1o4N2hmVWF4bGJDNW1jalNWaVlkTjhYUWdFVVBqZkNSR25qYW1sQnhxRVdVRFBscklhYWFQcUlCTnpvSkNlaElsb0JwcklGQW1xR0xhcDB6NVJKdEx5/callback',
30-12 05:54:26.624:     data: { type: 5, data: [Object] },
30-12 05:54:26.624:     auth: false
30-12 05:54:26.624:   },
30-12 05:54:26.624:   retries: 0
30-12 05:54:26.624: }
30-12 05:54:26.625: ApiResponse: Response {
30-12 05:54:26.625:   size: 0,
30-12 05:54:26.625:   timeout: 0,
30-12 05:54:26.625:   [Symbol(Body internals)]: {
30-12 05:54:26.625:     body: PassThrough {
30-12 05:54:26.625:       _readableState: [ReadableState],
30-12 05:54:26.625:       _events: [Object: null prototype],
30-12 05:54:26.625:       _eventsCount: 5,
30-12 05:54:26.625:       _maxListeners: undefined,
30-12 05:54:26.625:       _writableState: [WritableState],
30-12 05:54:26.625:       allowHalfOpen: true,
30-12 05:54:26.625:       [Symbol(kCapture)]: false,
30-12 05:54:26.625:       [Symbol(kCallback)]: null
30-12 05:54:26.625:     },
30-12 05:54:26.625:     disturbed: false,
30-12 05:54:26.625:     error: null
30-12 05:54:26.625:   },
30-12 05:54:26.625:   [Symbol(Response internals)]: {
30-12 05:54:26.625:     url: 'https://discord.com/api/v9/interactions/925975082281603083/aW50ZXJhY3Rpb246OTI1OTc1MDgyMjgxNjAzMDgzOmJ6dkx4OG5zMXV0TmlPUUI1UmZ1S1RHNTdobzVRYkZ6MjNRYVlzOVI3Z1o4N2hmVWF4bGJDNW1jalNWaVlkTjhYUWdFVVBqZkNSR25qYW1sQnhxRVdVRFBscklhYWFQcUlCTnpvSkNlaElsb0JwcklGQW1xR0xhcDB6NVJKdEx5/callback',
30-12 05:54:26.625:     status: 404,
30-12 05:54:26.625:     statusText: 'Not Found',
30-12 05:54:26.625:     headers: Headers { [Symbol(map)]: [Object: null prototype] },
30-12 05:54:26.625:     counter: undefined
30-12 05:54:26.625:   }
30-12 05:54:26.625: }
30-12 05:54:26.625: DiscordAPIError: Unknown interaction
30-12 05:54:26.625:     at RequestHandler.execute (/home/discord/Bull/node_modules/discord.js/src/rest/RequestHandler.js:350:13)
30-12 05:54:26.625:     at runMicrotasks (<anonymous>)
30-12 05:54:26.625:     at processTicksAndRejections (node:internal/process/task_queues:96:5)
30-12 05:54:26.625:     at async RequestHandler.push (/home/discord/Bull/node_modules/discord.js/src/rest/RequestHandler.js:51:14)
30-12 05:54:26.625:     at async CommandInteraction.deferReply (/home/discord/Bull/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:57:5)
30-12 05:54:26.625:     at async Object.execute (/home/discord/Bull/events/interactionCreate.js:143:25) {
30-12 05:54:26.625:   method: 'post',
30-12 05:54:26.625:   path: '/interactions/925975082281603083/aW50ZXJhY3Rpb246OTI1OTc1MDgyMjgxNjAzMDgzOmJ6dkx4OG5zMXV0TmlPUUI1UmZ1S1RHNTdobzVRYkZ6MjNRYVlzOVI3Z1o4N2hmVWF4bGJDNW1jalNWaVlkTjhYUWdFVVBqZkNSR25qYW1sQnhxRVdVRFBscklhYWFQcUlCTnpvSkNlaElsb0JwcklGQW1xR0xhcDB6NVJKdEx5/callback',
30-12 05:54:26.625:   code: 10062,
30-12 05:54:26.625:   httpStatus: 404,
30-12 05:54:26.625:   requestData: { json: { type: 5, data: [Object] }, files: [] }
30-12 05:54:26.625: }

And still when i convert my snowflake 925975082281603083 to the time, its 30-12-2021 05:54:23. Is there any way to check if there is a queue to prevent ratelimits? Because its really annoying to see sometime "Interaction failed" when you do a button or command.

jr0dd commented 2 years ago

I am also running into this issue. Been beating my head trying to find the cause. I am using the await interaction.deferReply() which does not help. I run into this whether I run in a container self-hosted in k8s or when running with just node.

logs

2022-01-05T10:28:13.806719883-05:00 stderr F DiscordAPIError: Unknown interaction
2022-01-05T10:28:13.807045369-05:00 stderr F     at RequestHandler.execute (/app/node_modules/discord.js/src/rest/RequestHandler.js:349:13)
2022-01-05T10:28:13.807053495-05:00 stderr F     at processTicksAndRejections (node:internal/process/task_queues:96:5)
2022-01-05T10:28:13.807056644-05:00 stderr F     at async RequestHandler.push (/app/node_modules/discord.js/src/rest/RequestHandler.js:50:14)
2022-01-05T10:28:13.807059908-05:00 stderr F     at async CommandInteraction.deferReply (/app/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:57:5)
2022-01-05T10:28:13.807062889-05:00 stderr F     at async Object.execute (/app/commands/stocks/chart.js:115:5)
2022-01-05T10:28:13.807065242-05:00 stderr F     at async Object.execute (/app/events/interactionCreate.js:9:7) {
2022-01-05T10:28:13.807067923-05:00 stderr F   method: 'post',
2022-01-05T10:28:13.807070813-05:00 stderr F   path: '/interactions/928308905921118238/aW50ZXJhY3Rpb246OTI4MzA4OTA1OTIxMTE4MjM4OmxVTHpGand1alpBbFhVeWVvVkFaTFBOVmZGZHI2QkdmM29pUndCbDJpaHJXNDZRd2N3WFYyTm9HbU5IN2ZpVnJvdWt0T0xTbTVrWVNoOG5OZG1QY2t1a1M4WHIzSHJaN21ESEZQQmhwWUhiNGhiSlk0Rk5UVjFZSDRuZmg4Skc5/callback',
2022-01-05T10:28:13.807073465-05:00 stderr F   code: 10062,
2022-01-05T10:28:13.8070758-05:00 stderr F   httpStatus: 404,
2022-01-05T10:28:13.807078359-05:00 stderr F   requestData: { json: { type: 5, data: [Object] }, files: [] }
2022-01-05T10:28:13.807081043-05:00 stderr F }
2022-01-05T10:28:13.888714872-05:00 stderr F /app/node_modules/discord.js/src/rest/RequestHandler.js:349
2022-01-05T10:28:13.888811365-05:00 stderr F       throw new DiscordAPIError(data, res.status, request);
2022-01-05T10:28:13.888833651-05:00 stderr F             ^
2022-01-05T10:28:13.888852779-05:00 stderr F
2022-01-05T10:28:13.888872533-05:00 stderr F DiscordAPIError: Unknown interaction
2022-01-05T10:28:13.88889315-05:00 stderr F     at RequestHandler.execute (/app/node_modules/discord.js/src/rest/RequestHandler.js:349:13)
2022-01-05T10:28:13.888912108-05:00 stderr F     at processTicksAndRejections (node:internal/process/task_queues:96:5)
2022-01-05T10:28:13.888928751-05:00 stderr F     at async RequestHandler.push (/app/node_modules/discord.js/src/rest/RequestHandler.js:50:14)
2022-01-05T10:28:13.888947067-05:00 stderr F     at async CommandInteraction.reply (/app/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:98:5) {
2022-01-05T10:28:13.888967383-05:00 stderr F   method: 'post',
2022-01-05T10:28:13.888986757-05:00 stderr F   path: '/interactions/928308905921118238/aW50ZXJhY3Rpb246OTI4MzA4OTA1OTIxMTE4MjM4OmxVTHpGand1alpBbFhVeWVvVkFaTFBOVmZGZHI2QkdmM29pUndCbDJpaHJXNDZRd2N3WFYyTm9HbU5IN2ZpVnJvdWt0T0xTbTVrWVNoOG5OZG1QY2t1a1M4WHIzSHJaN21ESEZQQmhwWUhiNGhiSlk0Rk5UVjFZSDRuZmg4Skc5/callback',
2022-01-05T10:28:13.889005564-05:00 stderr F   code: 10062,
2022-01-05T10:28:13.889024763-05:00 stderr F   httpStatus: 404,
2022-01-05T10:28:13.889046326-05:00 stderr F   requestData: {
2022-01-05T10:28:13.889065986-05:00 stderr F     json: {
2022-01-05T10:28:13.889083916-05:00 stderr F       type: 4,
2022-01-05T10:28:13.889118936-05:00 stderr F       data: {
2022-01-05T10:28:13.889138149-05:00 stderr F         content: 'There was an error while executing this command!',
2022-01-05T10:28:13.889156345-05:00 stderr F         tts: false,
2022-01-05T10:28:13.889174907-05:00 stderr F         nonce: undefined,
2022-01-05T10:28:13.889193018-05:00 stderr F         embeds: undefined,
2022-01-05T10:28:13.889211485-05:00 stderr F         components: undefined,
2022-01-05T10:28:13.889228528-05:00 stderr F         username: undefined,
2022-01-05T10:28:13.88924676-05:00 stderr F         avatar_url: undefined,
2022-01-05T10:28:13.889330775-05:00 stderr F         allowed_mentions: undefined,
2022-01-05T10:28:13.889354794-05:00 stderr F         flags: 64,
2022-01-05T10:28:13.889372654-05:00 stderr F         message_reference: undefined,
2022-01-05T10:28:13.889392604-05:00 stderr F         attachments: undefined,
2022-01-05T10:28:13.889410911-05:00 stderr F         sticker_ids: undefined
2022-01-05T10:28:13.88943035-05:00 stderr F       }
2022-01-05T10:28:13.889458082-05:00 stderr F     },
2022-01-05T10:28:13.889484572-05:00 stderr F     files: []
2022-01-05T10:28:13.889497436-05:00 stderr F   }
2022-01-05T10:28:13.889508506-05:00 stderr F }
2022-01-05T10:28:13.889519181-05:00 stderr F
2022-01-05T10:28:13.889530416-05:00 stderr F Node.js v17.3.0

code

const { SlashCommandBuilder } = require('@discordjs/builders')
const { MessageAttachment, MessageEmbed } = require('discord.js')
const nodeHtmlToImage = require('node-html-to-image')

module.exports = {
  data: new SlashCommandBuilder()
    .setName('chart')
    .setDescription('Pull up a chart')
    .addStringOption(option => option
      .setName('symbol')
      .setDescription('Enter symbol')
      .setRequired(true)
    )
    .addStringOption(option => option
      .setName('interval')
      .setDescription('Interval')
      .setRequired(true)
      .addChoice('1m', '1')
      .addChoice('5m', '5')
      .addChoice('15m', '15')
      .addChoice('1h', '60')
      .addChoice('1d', 'D')
      .addChoice('weekly', 'W')
      .addChoice('monthly', 'M')
    ),

  async execute (interaction) {
    const symbol = interaction.options.getString('symbol')
    const interval = interaction.options.getString('interval')
    const _htmlTemplate = `<html>
        <head>
        <style>
          body {
            width: 800px;
            height: 600px;
          }
        </style>
        </head>
        <body>
        <!-- TradingView Widget BEGIN -->
        <div class="tradingview-widget-container">
          <div id="tradingview_c4d70"></div>
          <script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script>
          <script type="text/javascript">
          new TradingView.widget(
          {
          "width": 800,
          "height": 600,
          "symbol": "${symbol}",
          "interval": "${interval}",
          "timezone": "America/New_York",
          "theme": "dark",
          "style": "1",
          "locale": "en",
          "toolbar_bg": "#f1f3f6",
          "enable_publishing": false,
          "hide_top_toolbar": true,
          "allow_symbol_change": false,
          "save_image": false,
          "studies": [
            "MACD@tv-basicstudies"
          ],
          "container_id": "tradingview_c4d70"
        }
          );
          </script>
        </div>
        <!-- TradingView Widget END -->
        </body>
        </html>
        `

    const image = await nodeHtmlToImage({
      html: _htmlTemplate,
      puppeteerArgs: {
        args: [
          '--disable-gpu',
          '--no-sandbox',
          '--disable-setuid-sandbox',
          '--disable-dev-shm-usage',
          '--headless'
        ]
      }
    })

    let period = interval
    if (period === '1') {
      period = '1min'
    }
    if (period === '5') {
      period = '5min'
    }
    if (period === '15') {
      period = '15min'
    }
    if (period === '60') {
      period = '1hr'
    }
    if (period === 'D') {
      period = 'Daily'
    }
    if (period === 'W') {
      period = 'Weekly'
    }
    if (period === 'M') {
      period = 'Monthly'
    }

    const file = new MessageAttachment(image, `${symbol}.png`)
    const embed = new MessageEmbed()
      .setTitle(`${symbol.toUpperCase()} ${period}`)
      .setImage(`attachment://${symbol}.png`)
      .setColor('#36393E')

    await interaction.deferReply()
    await interaction.editReply({ embeds: [embed], files: [file] })
      .catch(err => {
        interaction.reply('Error: There was a glitch in the matrix.')
        return console.error(err)
      })
  }
}
Jiralite commented 2 years ago

Deferring is the first action you should be doing, not the last. If it's the last, you might as well not do it at all?

jr0dd commented 2 years ago

Deferring is the first action you should be doing, not the last. If it's the last, you might as well not do it at all?

Ah I see. let me move under the async execute and see if that helps. Thanks!

jr0dd commented 2 years ago

Deferring is the first action you should be doing, not the last. If it's the last, you might as well not do it at all?

Thank you so much, that definitely fixed me up. Now if I can just figure out how to handle the iOS app from complaining about not a valid choice because iOS adds that trailing space to the last option....image

imranbarbhuiya commented 2 years ago

Deferring is the first action you should be doing, not the last. If it's the last, you might as well not do it at all?

Thank you so much, that definitely fixed me up. Now if I can just figure out how to handle the iOS app from complaining about not a valid choice because iOS adds that trailing space to the last option....image

This is neither related to this issue not with discord.js. It's related to discord.

advaith1 commented 2 years ago

it's a known bug with the Discord iOS app, just hit backspace before sending.

jr0dd commented 2 years ago

it's a known bug with the Discord iOS app, just hit backspace before sending.

Yeah I know just venting really 😂. Defer is working properly for me now so I'm happy!

Akoummanos commented 2 years ago

Hello! I have the same issue with unknown interaction. I have a code which track the time that a person is on duty. In my pc it works perfectly however in the server that i have the bot running i have the error unknown interaction, the code:

client.on('interactionCreate',async(interaction)=>{

    if(!interaction.isButton()) return;

    if(interaction.customId === "ondutybutton"){

        await interaction.deferReply()
        if (!interaction.member.roles.cache.has(configs.roles.STAFF)) {
            return await interaction.editReply({
                ephemeral: true,
                embeds:[
                    new Discord.MessageEmbed()
                    .setDescription(`\*\*Για να χρησιμοποιήσεις το \`DutySystem\` πρέπει να έχεις το <@&${configs.roles.STAFF}>!\*\*`)
                    .setColor("#ff001e")
                    .setFooter({text:configs.bot.NAME,iconURL: configs.bot.LOGO})
                ]
            });
        };

        let check = await tempHourschema.findOne({
            guildID:interaction.guild.id,
            staffID:interaction.user.id
        })
        if(check){ return await interaction.editReply({ ephemeral:true, embeds:[
            new Discord.MessageEmbed()
            .setDescription(`Είσαι σε υπηρεσία!`)
            .setAuthor({name: interaction.user.username, iconURL:interaction.user.displayAvatarURL({dynamic:true})})
            .setColor(configs.bot.COLOR)
        ]})}
        let start = new Date().getTime();

        let schema = new tempHourschema({
            _id: mongoose.Types.ObjectId(),
            guildID: interaction.guild.id,
            staffID: interaction.user.id,
            startTime: start

        })
        schema.save()
        .catch(err => console.error(err));
        await interaction.editReply({
            ephemeral:true,
            embeds:[
                new Discord.MessageEmbed()
                .setDescription(`\*\*<:online:885183255823925319> Μπήκες σε υπηρεσία!\*\*`)
                .setAuthor({name: interaction.user.username, iconURL:interaction.user.displayAvatarURL({dynamic:true})})
                //.setTimestamp()
                .setColor('#30ff45')
            ]
        })

    } 

})
imranbarbhuiya commented 2 years ago

Hello! I have the same issue with unknown interaction. I have a code which track the time that a person is on duty. In my pc it works perfectly however in the server that i have the bot running i have the error unknown interaction, the code:

client.on('interactionCreate',async(interaction)=>{

    if(!interaction.isButton()) return;

    if(interaction.customId === "ondutybutton"){

        await interaction.deferReply()
        if (!interaction.member.roles.cache.has(configs.roles.STAFF)) {
            return await interaction.editReply({
                ephemeral: true,
                embeds:[
                    new Discord.MessageEmbed()
                    .setDescription(`\*\*Για να χρησιμοποιήσεις το \`DutySystem\` πρέπει να έχεις το <@&${configs.roles.STAFF}>!\*\*`)
                    .setColor("#ff001e")
                    .setFooter({text:configs.bot.NAME,iconURL: configs.bot.LOGO})
                ]
            });
        };

        let check = await tempHourschema.findOne({
            guildID:interaction.guild.id,
            staffID:interaction.user.id
        })
        if(check){ return await interaction.editReply({ ephemeral:true, embeds:[
            new Discord.MessageEmbed()
            .setDescription(`Είσαι σε υπηρεσία!`)
            .setAuthor({name: interaction.user.username, iconURL:interaction.user.displayAvatarURL({dynamic:true})})
            .setColor(configs.bot.COLOR)
        ]})}
        let start = new Date().getTime();

        let schema = new tempHourschema({
            _id: mongoose.Types.ObjectId(),
            guildID: interaction.guild.id,
            staffID: interaction.user.id,
            startTime: start

        })
        schema.save()
        .catch(err => console.error(err));
        await interaction.editReply({
            ephemeral:true,
            embeds:[
                new Discord.MessageEmbed()
                .setDescription(`\*\*<:online:885183255823925319> Μπήκες σε υπηρεσία!\*\*`)
                .setAuthor({name: interaction.user.username, iconURL:interaction.user.displayAvatarURL({dynamic:true})})
                //.setTimestamp()
                .setColor('#30ff45')
            ]
        })

    } 

})

If it's working in your pc then it's definitely the issue of your hosting where it's deferring the interaction after 3s

ikheetjeff commented 2 years ago

I have this problem when things get very busy (multiple requests per second). When it is quiet not at all. I can't do a defer earlier than I already have.

What is the plan now? I would love to have this resolved but don't know how. I would like to release a public bot but with these reports it is a waste of work in my opinion.

philipaarseth commented 2 years ago

@Akoummanos Try temporarily turning off your server and see if you still have a problem. Interactions can only be replied to once. If you're running the server at the same time as your dev environment, afaik they'll both try and intercept the interaction and one of them will get interaction unknown.

Akoummanos commented 2 years ago

Well, i tried it with a different server and still nothing...I dont know what to do.

Akoummanos commented 2 years ago

Problem fixed! I didn't know what to do and started doing everything that I can change in my bot. I regenerated my token and it finally worked. Iam assuming that a second bot was running with the same token.

Pickysaurus commented 2 years ago

I too am seeing this error at random intervals. I've properly awaited all my defers. The most frustrating thing for me is that it seems impossible to catch this error. It just closes down the app with Exit Code 1.

DJCoolDev commented 2 years ago

I had this problem for a very long time with my bots. The more the bots grew, the more often I got the "Unknown Interaction" error. I searched a lot and finally found a solution for me for this problem. I was changing the status of the bots every 20 seconds and I don't really know why, but after removing that I don't get the error now. I will keep watching to see if it is just a coincidence or if this really solved my problem. Does anyone know if this really helps and if so why?

Pickysaurus commented 2 years ago

It feels like it's a race condition of some kind. The error itself seems to come from this in the Interaction Class somehow becoming undefined. My stack trace refers to this.deferred causing the crash because this is not properly defined (somehow?)

Pickysaurus commented 2 years ago
2/7/2022, 2:00:15 PM - Error replying to failed interaction {
  replyError: TypeError: Cannot read properties of undefined (reading 'deferred')
      at editReply (/home/discordbot/discord-bot/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:138:15)
      at /home/discordbot/discord-bot/dist/events/interactionCreate.js:35:24
      at processTicksAndRejections (node:internal/process/task_queues:96:5),
  serverId: '327809947272478720',
  serverName: 'Blade & Sorcery',
  channelName: '<#583723053679378432>',
  requestedBy: 'kajimishima#7181',
  botVersion: '3.1.3',
  interaction: '/refresh',
  error: 'Unknown interaction'
}
Cl00e9ment commented 2 years ago

I had the same issue for a quite while and I fixed it this night, yeah! It was a painful debugging but now I have a better understanding of why this is happening. The "fix" was just stopping calling client.user.setActivity every minute. I'll try to explain it:

The client.user.setActivity call is causing the client to not receive anything from the API for many seconds. Why? idk. After this delay, the client receive all the interactions at once. A good chunk of these interactions are now too old and replying to them will cause a DiscordAPIError: Unknown interaction. For the user, it displays This interaction failed.

Why is this issue hard to reproduce in the dev env? Because you have to send your interaction just before a client.user.setActivity call. In production, with users interacting constantly with the bot, it happens very often (every minute in my case).

I've attached a ZIP with some CPU profiles. You can open them with Chrome or Chromium: go to chrome://inspect/ > Open dedicated DevTools for Node > Profiler > Load and then choose to display the chart.

As you can see on the charts, there is a 4s blank when nothing happen. Just before the blank you can see the call to setActivity. If you pay attention, you can even see a call to Logger.error after the blank, during a onInteraction call.

Hope this helps!

advaith1 commented 2 years ago

The client.user.setActivity call is causing the client to not receive anything from the API for many seconds.

Setting presence is blocking in Discord, that's the intentional gateway behavior

Cl00e9ment commented 2 years ago

Setting presence is blocking in Discord, that's the intentional gateway behavior

Then I guess this issue is "fixed"? But how one is supposed to modify the activity without causing some issues with the interactions? One can't even defer the interactions since they are already too old.

Cl00e9ment commented 2 years ago

Seams like DiscordAPIError: Unknown interaction is still occurring, just way less often. Maybe running the process with the profiler will help diagnose this issue. I'll try that tomorrow.

EDIT: Now that I don't use setActivity anymore, only 0.1% of the interactions ends up with an Unknown interaction error. My assumption is that it's just network lag. It's hard to run the profiler on the bot because I can't run the profiler during hours waiting for the bug to happen (the generated file would be huge).

jgreens commented 2 years ago

Problem fixed! I didn't know what to do and started doing everything that I can change in my bot. I regenerated my token and it finally worked. Iam assuming that a second bot was running with the same token.

Thank you so much @Akoummanos! That fixed it for me.

Yippy commented 2 years ago

I believe that there is a limit of failed interactions on discord, I've been testing and crashing my bot on purpose to try capturing error conditions. Maybe like every 10 minutes?

Then suddenly I came across that the interaction just becomes invalid by Discord, image went to bed, just start the bot with the same source code image Now the interaction is now valid, you are probably best to get a new token than to wait for Discord. image

Just wanted to clarify that I have two bots, with two different tokens, one live and the other is beta for testing. Beta bot crashes alot when I test, so there is no sharing race condition issue. It just that Discord stop accepting the interaction as valid... no matter what I've tried.

Edit----- 2020-02-20 okay, after going live with the new interaction buttons. This bug appears randomly..... doesn't matter if you was crashing/testing/etc.

z1haze commented 2 years ago

I have been having this issue plaguing my bots for a very long time now. When asked for a case that can be reproduced, it is very hard as the issue is sporatic. 1/50 attempts may result in this, nothing different among them. Really wish this could be fixed.

SDCore commented 2 years ago

I also wanna bring this up because I've been having this issue for months, and it's near impossible to properly find a cause for it. I thought it was an issue with an API I was using. I spent weeks optimizing it and beefing up the server infrastructure for it and it was never the actual cause of the issue. I rewrote the bot several times, maybe thinking it was the way I was registering slash commands, but nope, no matter what I did it still threw the error.

It seems to happen when the interaction checks for the command to use it. I've thrown a defer in there just now but we'll see what happens. I only change the status of the bot when it launches and it's static so it otherwise doesn't change when the bots running.

Lioness100 commented 2 years ago

I also have this issue, and I don't do anything with the bot's status.

Cl00e9ment commented 2 years ago

I think it's 2 different issues with the same symptoms. After stopping to refresh the status, the error is occurring a lot less, but it's still occurring. So it also have to come elsewhere.

advaith1 commented 2 years ago

This error is only returned if you are trying to respond to an interaction after the 3 second timeout. Updating presence (such as using setActivity) freezes the connection for a bit, which is why that can contribute to it taking over 3 seconds for you to respond.

There is no issue/bug here, it's just intended Discord functionality.