Discord.js: bot crashes with uncatchable error from members.fetch

Created on 8 Oct 2020  Â·  13Comments  Â·  Source: discordjs/discord.js

Please describe the problem you are having in as much detail as possible:
When running message.guild.members.fetch({ user: [] }) with an invalid snowflake like a
ex message.guild.members.fetch({ user: ['a', '1'] }) it seems to crash the node process without any errors. Even a catch doesn't handle it since there's no error thrown. Then after exactly 120 seconds the bot makes a successful connection to the gateway in which it then throws the error but the node process is still in a crashed state in which the bot never fully reconnected. I do use PM2 so pm2 is configured to restart a crashed node process. Though the process isn't fully crashed. The only thing that's emitted in the console is from the Shard reconnect event right when the bot goes offline.

You can view the video I recorded of it happening here https://streamable.com/f3y0mm once you reach the 11 second mark you can skip the video to the 2 minute mark, everything between that is just untrimmed video of it showing it's still offline. But at the 2:11 mark you can see the bot throws the error but is still offline.

With the debug logs enabled this is all that's emitted

[2020-10-08 17:03:12] [WS => Shard 0] [INVALID SESSION] Resumable: false.
[2020-10-08 17:03:12] [SHARD RECONNECTING] Shard 0

Include a reproducible code sample here, if possible:

message.guild.members.fetch({ user: ['a', '1'] })

Further details:

  • discord.js version: master
  • Node.js version: v14.12.0
  • Operating system: Ubuntu 18.04
  • Priority this issue should have – please be realistic and elaborate if possible: medium-high. Medium since you shouldn't be providing invalid snowflakes anyways and high since it causes a crash/delay that has no way of handling it.

Relevant client options:

  • partials: none
  • gateway intents: none
  • other: none
  • [x] I have also tested the issue on latest master, commit hash: d234165
medium gateway bug

All 13 comments

Looks Legit

discord.js is a totally buggy library I stopped using it there are too many concerns and the community does not have the skills.

I wasted way too much time with them I advise you to use something else.

I did some debugging.

The main problem here is that the Shard does not reconnect upon receiving opcode 9 (INVALID_SESSION).

I'll look into fixing that.

As for the reason why we receive opcode 9: no idea.
When we send opcode 8 (REQUEST_GUILD_MEMBERS) with invalid user_ids, the gateway hangs for about 3 seconds, after which invalid session is received. I'm assuming this is because this edge-case is not handled on Discord's end and it kind of explodes. During those 3 seconds the shard cannot send other messages to the gateway because of our queue mechanism. And since the INVALID_SESSION pretty much resets the shard, any packets that were queued during those 3 seconds are lost.

I did some poking around and noticed that this only happens when the sent user_ids are not snowflakes. If they are snowflakes but not belonging to users the gateway responds just fine. So I guess the solution here would be to make sure that the sent user_ids are valid snowflakes. I'm not sure what class would be best to delegate that responsibility to, but I think we could patch the BaseManager and make resolveID enforce snowflake format for strings. The way string are handled currently is kind of meh: https://github.com/discordjs/discord.js/blob/master/src/managers/BaseManager.js#L72

@BannerBomb it seems while my PR was open Discord managed to fix this on their end. Fetching members/users with non-numeric IDs is now handled correctly on their end and should, in turn, fix your situation. Please confirm that you no longer see the described behavior.

@TeeSeal I updated my bot today but am still noticing the same issue.
image

The bot still goes offline and doesn't come back online. Still sends the timed out message after 120 seconds while offline, and debug event is still printing

[2020-10-27 22:00:48] [WS => Shard 0] [INVALID SESSION] Resumable: false.
[2020-10-27 22:00:48] [SHARD RECONNECTING] Shard 0

At the time of writing this my specs are now
Partials: None
Intents: None
Other: None
Node.js: v14.14.0
Discord.js: 12.4.1 [master] (Branch Commit: 7ec0bd9)
Operating system:
Main OS: Ubuntu 18.04.3 LTS
OS in docker (where the node process is): Debian GNU/Linux 9 (stretch)

Update

The bot was able to restart automatically 5 minutes after throwing the members timed out error along with the debug event receiving this during the reconnection.

[2020-10-27 22:15:55] [WS => Shard 0] [INVALID SESSION] Resumable: false.
[2020-10-27 22:15:55] [SHARD RECONNECTING] Shard 0
[2020-10-27 22:20:00] [WS => Shard 0] [CLOSE]
[2020-10-27 22:20:00]     Event Code: 4003
[2020-10-27 22:20:00]     Clean     : true
[2020-10-27 22:20:00]     Reason    : Not authenticated.
[2020-10-27 22:20:00] [WS => Shard 0] Clearing the heartbeat interval.
[2020-10-27 22:20:00] [SHARD RECONNECTING] Shard 0
[2020-10-27 22:20:00] [WS => Shard 0] WS State: CLOSED
[2020-10-27 22:20:00] [WS => Manager] Session Limit Information
[2020-10-27 22:20:00]     Total: 1000
[2020-10-27 22:20:00]     Remaining: 986
[2020-10-27 22:20:00] [WS => Shard 0] [CONNECT]
[2020-10-27 22:20:00]     Gateway    : wss://gateway.discord.gg/
[2020-10-27 22:20:00]     Version    : 6
[2020-10-27 22:20:00]     Encoding   : json
[2020-10-27 22:20:00]     Compression: none
[2020-10-27 22:20:00] [WS => Shard 0] Setting a HELLO timeout for 20s.
[2020-10-27 22:20:00] [WS => Shard 0] [CONNECTED] wss://gateway.discord.gg/?v=6&encoding=json in 167ms
[2020-10-27 22:20:00] [WS => Shard 0] Clearing the HELLO timeout.
[2020-10-27 22:20:00] [WS => Shard 0] Setting a heartbeat interval for 41250ms.
[2020-10-27 22:20:00] [WS => Shard 0] [IDENTIFY] Shard 0/1
[2020-10-27 22:20:01] [WS => Shard 0] [READY] Session *************************.
[2020-10-27 22:20:01] [WS => Shard 0] Shard received all its guilds. Marking as fully ready.
[2020-10-27 22:20:01] [SHARD READY] Shard 0
[2020-10-27 22:22:01] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:317:16
[2020-10-27 22:22:01]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 22:22:01]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 22:22:01]     at processTimers (internal/timers.js:497:7)
[2020-10-27 22:22:01] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:317:16
[2020-10-27 22:22:01]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 22:22:01]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 22:22:01]     at processTimers (internal/timers.js:497:7)
[2020-10-27 22:22:01] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:317:16
[2020-10-27 22:22:01]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 22:22:01]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 22:22:01]     at processTimers (internal/timers.js:497:7)
[2020-10-27 22:22:01] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:317:16
[2020-10-27 22:22:01]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 22:22:01]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 22:22:01]     at processTimers (internal/timers.js:497:7)
[2020-10-27 22:22:01] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 22:22:01]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:317:16
[2020-10-27 22:22:01]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 22:22:01]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 22:22:01]     at processTimers (internal/timers.js:497:7)

Did you want me to try switching to the PR branch and test again?

Update 2

I went ahead and switched over to the branch of the PR in case that's what you intended for me to do. And The bot does experience some of the same stuff. The bot does go offline, but it also does resume it's connection quicker. However the timed out error is still thrown after 120 seconds.

The debug log on the PR branch shows.

[2020-10-27 23:03:27] [WS => Shard 0] [INVALID SESSION] Resumable: false.
[2020-10-27 23:03:27] [SHARD RECONNECTING] Shard 0
[2020-10-27 23:03:27] [WS => Manager] Session Limit Information
[2020-10-27 23:03:27]     Total: 1000
[2020-10-27 23:03:27]     Remaining: 981
[2020-10-27 23:03:27] [WS => Shard 0] An open connection was found, attempting an immediate identify.
[2020-10-27 23:03:27] [WS => Shard 0] [IDENTIFY] Shard 0/1
[2020-10-27 23:03:27] [WS => Shard 0] [READY] Session **************************************.
[2020-10-27 23:03:27] [WS => Shard 0] Shard received all its guilds. Marking as fully ready.
[2020-10-27 23:03:27] [SHARD READY] Shard 0
[2020-10-27 23:05:27] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:314:16
[2020-10-27 23:05:27]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 23:05:27]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 23:05:27]     at processTimers (internal/timers.js:497:7)
[2020-10-27 23:05:27] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:314:16
[2020-10-27 23:05:27]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 23:05:27]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 23:05:27]     at processTimers (internal/timers.js:497:7)
[2020-10-27 23:05:27] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:314:16
[2020-10-27 23:05:27]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 23:05:27]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 23:05:27]     at processTimers (internal/timers.js:497:7)
[2020-10-27 23:05:27] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:314:16
[2020-10-27 23:05:27]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 23:05:27]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 23:05:27]     at processTimers (internal/timers.js:497:7)
[2020-10-27 23:05:27] Failed to fetch all members: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27] Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
[2020-10-27 23:05:27]     at /opt/rookiebotelite/node_modules/discord.js/src/managers/GuildMemberManager.js:314:16
[2020-10-27 23:05:27]     at Timeout._onTimeout (/opt/rookiebotelite/node_modules/discord.js/src/client/BaseClient.js:83:7)
[2020-10-27 23:05:27]     at listOnTimeout (internal/timers.js:554:17)
[2020-10-27 23:05:27]     at processTimers (internal/timers.js:497:7)

🤔 That's weird, I tested today and didn't see the same behavior.

If it helps this is my client options.

const client = new Client({
    autoReconnect: true,
    retryLimit: 10,
    disableEveryone: true,
    disabledEvents: [
        'CHANNEL_PINS_UPDATE'
    ],
    fetchAllMembers: true,
    presence: {
        activity: {
            name: '...Powering up',
            type: 0
        }
    },
    restTimeOffset: 0
});

To get more information, I did some testing on a completely new stock bot environment and I am still getting the issue. The code I used is provided below.

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

const client = new Client({
    autoReconnect: true
});

client.on('message', async(message) => {
    if (message.guild) {
        if (message.content === 'r!test') {
            console.log('one'); // this is printed
            await message.guild.members.fetch({ user: ['a'] }).catch((error) => {
                console.error(error);
            }); // this is thrown after 120 seconds
            console.log('two'); // this is printed after 120 seconds (after the members timed out error is thrown)
        } else if (message.content === 'r!ping') {
            await message.channel.send('PONG!');
        }
    }
});

client.once('ready', () => {
    console.log('BOT READY!!!!!!!!!!');
});

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

client.on('error', (code) => {
    console.error(code);
});

process.on('exit', (code) => {
    console.log(code);
});

process.on('uncaughtException', (error) => {
    console.error(error);
});

process.on('unhandledRejection', (error) => {
    console.error(error);
});

client.login('...');

Without filtering the debug logs, the client crashes but is still sending heartbeats then 120 seconds later the members timed out error is thrown.

debug logs show

Provided token: ***************************.***************************
Preparing to connect to the gateway...
[WS => Manager] Fetched Gateway Information
    URL: wss://gateway.discord.gg
    Recommended Shards: 1
[WS => Manager] Session Limit Information
    Total: 1000
    Remaining: 955
[WS => Manager] Spawning shards: 0
[WS => Shard 0] [CONNECT]
    Gateway    : wss://gateway.discord.gg/
    Version    : 6
    Encoding   : json
    Compression: none
[WS => Shard 0] Setting a HELLO timeout for 20s.
[WS => Shard 0] [CONNECTED] wss://gateway.discord.gg/?v=6&encoding=json in 141ms
[WS => Shard 0] Clearing the HELLO timeout.
[WS => Shard 0] Setting a heartbeat interval for 41250ms.
[WS => Shard 0] [IDENTIFY] Shard 0/1
[WS => Shard 0] [READY] Session ***************************.
[WS => Shard 0] [ReadyHeartbeat] Sending a heartbeat.
[WS => Shard 0] Shard received all its guilds. Marking as fully ready.
BOT READY!!!!!!!!!!
[WS => Shard 0] Heartbeat acknowledged, latency of 399ms.
one
[WS => Shard 0] [INVALID SESSION] Resumable: false.
[WS => Shard 0] [HeartbeatTimer] Sending a heartbeat.
[WS => Shard 0] Heartbeat acknowledged, latency of 39ms.
[WS => Shard 0] [HeartbeatTimer] Sending a heartbeat.
[WS => Shard 0] Heartbeat acknowledged, latency of 45ms.
Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
    at /mnt/c/Users/Admin/Desktop/testbpt/node_modules/discord.js/src/managers/GuildMemberManager.js:317:16
    at Timeout._onTimeout (/mnt/c/Users/Admin/Desktop/testbpt/node_modules/discord.js/src/client/BaseClient.js:83:7)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7) {
  [Symbol(code)]: 'GUILD_MEMBERS_TIMEOUT'
}
two
[WS => Shard 0] [HeartbeatTimer] Sending a heartbeat.
[WS => Shard 0] Heartbeat acknowledged, latency of 30ms.
[WS => Shard 0] [HeartbeatTimer] Sending a heartbeat.
[WS => Shard 0] Heartbeat acknowledged, latency of 31ms.
[WS => Shard 0] [HeartbeatTimer] Sending a heartbeat.
[WS => Shard 0] Heartbeat acknowledged, latency of 30ms.

while the client is offline it's still sending heartbeats but not reconnecting. Without PM2 being used the client didn't reconnect at all. Even with autoReconnect: true specified.

While trying your PR branch on the stock code the bot did reconnect automatically but it still throws the members timed out error after 120 seconds also. If I use the autoReconnect: true client option with this branch the bot does go offline then reconnects, but if I don't provide the option it re-connects without going offline. But either way the error isn't thrown until 120 seconds after it crashed.

@BannerBomb, understood. I might have used the wrong branch when testing myself. Now I'm getting the same behavior you do, without any changes.

If you try my PR branch now it should prevent the client from getting an invalid session completely. Though, the changes are a bit out of place tbh so we're a bit skeptical about them. The main problem lies with the Discord gateway, which explodes upon receiving a non-numeric ID when fetching members/users. =/

@TeeSeal No problem, I have just tested the pr branch and can confirm the issue is fixed with it.

Running v12.4.1 on Windows 10 every time I run await guild.members.fetch() I get the same error as above.
Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.

For additional context, I've been using guild.members.cache.map... to locate channel users. However, I removed and readded my bot from a channel a few times to test a different feature. After readding my guild.members.cache only has 2 members. So I went down the path of members.fetch() to refresh the cache but I am getting this timeout now :/

Figured I'd post this here as it seems like a related. LMK if I should open a separate issue.

Edit: Manually @<username> on my server updated the cache. This is my current work around, basically ping everyone so they're available for my bot.

Seems like an intents issue, see the guide regarding gateway intents.

Members not arriving in time is not what this issue is about. Please stop posting about this here. As @Extroonie mentioned you're most likely having an intents issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Lombra picture Lombra  Â·  3Comments

LLamaFTL picture LLamaFTL  Â·  3Comments

Acaretia picture Acaretia  Â·  3Comments

Blumlaut picture Blumlaut  Â·  3Comments

PassTheMayo picture PassTheMayo  Â·  3Comments