Bot Appearing Offline on Some Shards

I’m running a bot on 635K servers, using discord-hybrid-sharding and discord-cross-hosting for efficient shard management. The setup works fine at the beginning, but after 6-7 hours of uptime, I experience the following issues: 1 Bot appears offline in some Discord servers (specific shards seem to stop functioning or disconnect). 2 .stats command fails to return the correct total guilds and user count after 6-7 hours of operation. I've been experiencing a problem My Bot Appearing Offline in some Discord servers (shards) despite all clusters being online and functioning normally. There are no shardDisconnect event calls, and everything seems to be connected correctly based on the logs. I've consulted the discord-cross-hosting support server, and they mentioned it's unlikely to be a hybrid hosting issue, suggesting it might be related to Discord.js or a network problem. However, after troubleshooting this issue for the past 6-7 days and asking for help in multiple servers, I haven't found a solution. The bot connects and resumes fine, with no disconnect events. All shards are sending heartbeat acknowledgements, but the bot is still shown as offline in certain servers. Could an expert please help me debug this? I'm stuck and not sure what to do next. Any help would be greatly appreciated!
25 Replies
d.js toolkit
d.js toolkit2mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
dev_panda
dev_pandaOP2mo ago
Server.ts
const { Bridge } = require('discord-cross-hosting');
import dotenv from "dotenv"
dotenv.config();

const server = new Bridge({
port: 5050,
authToken: process.env.AUTH_TOKEN,
totalShards: 656,
totalMachines: 2,
shardsPerCluster: 8,
token: process.env.TOKEN,
});

server.on('debug', console.log);
server.start();
server.on('ready', url => {
console.log('Server is ready' + url);
setInterval(() => {
server.broadcastEval('this.guilds.cache.size').then(console.log).catch(console.log);
}, 10000);
});
const { Bridge } = require('discord-cross-hosting');
import dotenv from "dotenv"
dotenv.config();

const server = new Bridge({
port: 5050,
authToken: process.env.AUTH_TOKEN,
totalShards: 656,
totalMachines: 2,
shardsPerCluster: 8,
token: process.env.TOKEN,
});

server.on('debug', console.log);
server.start();
server.on('ready', url => {
console.log('Server is ready' + url);
setInterval(() => {
server.broadcastEval('this.guilds.cache.size').then(console.log).catch(console.log);
}, 10000);
});
index.ts
const { Client } = require('discord-cross-hosting');
import { ClusterManager, HeartbeatManager, ReClusterManager } from 'discord-hybrid-sharding';
import dotenv from 'dotenv';

dotenv.config();

const client = new Client({
agent: 'bot',
host: '111.666.4.666',
port: 0000,
authToken: process.env.AUTH_TOKEN,
rollingRestarts: false,
});

client.connect();

client.on('ready', () => {
console.log('Cluster Client is ready');
});

const manager = new ClusterManager(`${__dirname}/src/musico.js`, {
totalShards: 328,
totalClusters: 33,
mode: 'process',
token: process.env.TOKEN,
});

manager.extend(
new HeartbeatManager({
interval: 5000,
maxMissedHeartbeats: 5,
}),
new ReClusterManager()
);

manager.on('clusterCreate', cluster => {
console.log(`Launched Cluster ${cluster.id}`);
});

client.listen(manager);
client
.requestShardData()
.then(e => {
if (!e) return;
manager.totalShards = e.totalShards;
manager.totalClusters = e.shardList.length;
manager.shardList = e.shardList;
manager.clusterList = e.clusterList;
manager.spawn({ timeout: -1 });
})
.catch(e => console.log(e));
const { Client } = require('discord-cross-hosting');
import { ClusterManager, HeartbeatManager, ReClusterManager } from 'discord-hybrid-sharding';
import dotenv from 'dotenv';

dotenv.config();

const client = new Client({
agent: 'bot',
host: '111.666.4.666',
port: 0000,
authToken: process.env.AUTH_TOKEN,
rollingRestarts: false,
});

client.connect();

client.on('ready', () => {
console.log('Cluster Client is ready');
});

const manager = new ClusterManager(`${__dirname}/src/musico.js`, {
totalShards: 328,
totalClusters: 33,
mode: 'process',
token: process.env.TOKEN,
});

manager.extend(
new HeartbeatManager({
interval: 5000,
maxMissedHeartbeats: 5,
}),
new ReClusterManager()
);

manager.on('clusterCreate', cluster => {
console.log(`Launched Cluster ${cluster.id}`);
});

client.listen(manager);
client
.requestShardData()
.then(e => {
if (!e) return;
manager.totalShards = e.totalShards;
manager.totalClusters = e.shardList.length;
manager.shardList = e.shardList;
manager.clusterList = e.clusterList;
manager.spawn({ timeout: -1 });
})
.catch(e => console.log(e));
logs1 | [WS => Shard 124] Heartbeat acknowledged, latency of 107ms. 1 | [WS => Shard 265] Heartbeat acknowledged, latency of 105ms. 1 | [WS => Shard 125] Heartbeat acknowledged, latency of 111ms. 1 | [WS => Shard 267] Heartbeat acknowledged, latency of 115ms. 1 | [WS => Shard 19] Heartbeat acknowledged, latency of 105ms. 1 | [WS => Shard 300] Heartbeat acknowledged, latency of 106ms. 1 | [WS => Shard 117] Heartbeat acknowledged, latency of 107ms. 1 | [WS => Shard 118] Heartbeat acknowledged, latency of 111ms. 1 | [WS => Shard 133] Destroying shard 1 | Reason: Told to reconnect by Discord 1 | Code: 4200 1 | Recover: Resume 1 | [WS => Shard 133] Connection status during destroy 1 | Needs closing: true 1 | Ready state: 1 1 | [WS => Shard 202] Heartbeat acknowledged, latency of 106ms. 1 | [WS => Shard 233] Heartbeat acknowledged, latency of 112ms. 1 | [WS => Shard 150] Heartbeat acknowledged, latency of 105ms. 1 | [WS => Shard 133] Connecting to wss://gateway-us-east1-c.discord.gg?v=10&encoding=json 1 | [WS => Shard 133] Waiting for event hello for 60000ms 1 | [WS => Shard 133] Resuming session 1 | resume url: wss://gateway-us-east1-c.discord.gg 1 | sequence: 32204 1 | shard id: 133 1 | [WS => Shard 133] Resumed and replayed 5 events
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
dev_panda
dev_pandaOP2mo ago
I've been using Discord.js as my main library
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
dev_panda
dev_pandaOP2mo ago
i asked their support server, and they mentioned it's unlikely to be a hybrid hosting issue, suggesting it might be related to Discord.js or a network problem
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
dev_panda
dev_pandaOP2mo ago
i'll do that now and try to reproduce the issue.
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
dev_panda
dev_pandaOP2mo ago
Alright i will tell them about this
DD
DD2mo ago
hi. I maintain most of the websocket code. I see people with situations like yours pop up every few months, and it's almost always someone using some 3rd party sharding solutions that we don't provide quite frankly, I don't know what to tell you. the debug logs you provided imply everything is fine, shards don't simply disappear without any logs indicating they're about to disconnect, so-and-so the maintainers of the packagers you're using are most likely, quite frankly, delusional :meguFace: and while that may sound rude, no one has been able to show me to how to reproduce this "shard magically disappearing" stuff with just discord.js/@discordjs/ws
sean
sean2mo ago
Hybrid does nothing more than spawing a child process or worker process of your index.js after that you specify shards and shardCount in the client construcutre its really just a process manager in order to cluster your bot based on internal sharding nothing more so a basic reproduction would be a ton of child processes with shardCount: 8 shardIds: [0, 1, 2, 3, 4, 5, 6, 7] and change the shardIds with the next pair if you want to try to reproduce it with djs/ws The thing is this issue as you already said only comes some times every few months, myself I cannot reproduce that with a over 1300 shards bot nor with a 14 shards bot. Most users that have this issue ignore it until it just dosnt happen anymore. side info which isnt that important Hybird spawns a worker with
return (this.process = new Worker_Thread(this.file, this.workerOptions));
return (this.process = new Worker_Thread(this.file, this.workerOptions));
and a child process with
return (this.process = fork(this.file, this.args, this.processOptions));
return (this.process = fork(this.file, this.args, this.processOptions));
DD
DD2mo ago
Hi! Let me know when you're actually reproduced it without hybrid & have associated debug logs. Thank you!
ɅV
ɅV2mo ago
Make sure you don't have any code blocking processes. i.e. infinite cycles
Iced Queen
Iced Queen4w ago
I have this same issue where it shows an incorrect guild and user count after X hours of operation, without discord-hybrid-sharding though. Have you found a solution yet?
pat
pat4w ago
if you get debug logs im sure the maintainer of ws will be happy to help (as above)
Iced Queen
Iced Queen3w ago
What would I even debug log? I do not use a 3rd party sharding library and I have the same issue 😅 Or partly the same issue
DD
DD3w ago
literally the debug event
Iced Queen
Iced Queen3w ago
Event of what? I assumed it would be a shard event but it ain't, unless I'm not looking in the right place? OOh just a client event... sorry me slow
DD
DD3w ago
:meguFace:
Iced Queen
Iced Queen3w ago
So what kind of debug looks would I be looking for whenever the issue occurs? If you have any idea Alright I will get back whenever it occurs again :)) I didn't even know there was a "debug" event.. well I do now :theshrug: So these are the debug logs from the time between it giving correct guild and member counts to now where it doesn't. I am not really sure what I would be looking for though https://codeshare.io/Ek0QNo Before restart: Server Count: 34,726 Member Count: 21,783 After restart: Server Count: 34,697 Member Count: 1,367,868
const promises = [
client.shard.broadcastEval(c => c.guilds.cache.size)
.catch(error => {
console.error(new Date(), `Error in guild count for shard:`, error);
return 0;
}),
client.shard.broadcastEval(c => c.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0))
.catch(error => {
console.error(new Date(), `Error in member count for shard:`, error);
return 0;
}),
client.shard.broadcastEval(c => c.ws.status === 0 ? true : false)
.catch(error => {
console.error(new Date(), `Error in shard connection status:`, error);
return false;
})
];

let totalGuilds;
let totalMembers;
let responsiveShards;
await Promise.all(promises.map(promise =>
Promise.resolve(promise)
))
.then(results => {
totalGuilds = results[0].reduce((acc, guildCount) => acc + guildCount, 0);
totalMembers = results[1].reduce((acc, memberCount) => acc + memberCount, 0);
responsiveShards = results[2].filter(responsive => responsive).length;
})
.catch(error => {
console.error(new Date(), `Error fetching shard data:`, error);
});
const promises = [
client.shard.broadcastEval(c => c.guilds.cache.size)
.catch(error => {
console.error(new Date(), `Error in guild count for shard:`, error);
return 0;
}),
client.shard.broadcastEval(c => c.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0))
.catch(error => {
console.error(new Date(), `Error in member count for shard:`, error);
return 0;
}),
client.shard.broadcastEval(c => c.ws.status === 0 ? true : false)
.catch(error => {
console.error(new Date(), `Error in shard connection status:`, error);
return false;
})
];

let totalGuilds;
let totalMembers;
let responsiveShards;
await Promise.all(promises.map(promise =>
Promise.resolve(promise)
))
.then(results => {
totalGuilds = results[0].reduce((acc, guildCount) => acc + guildCount, 0);
totalMembers = results[1].reduce((acc, memberCount) => acc + memberCount, 0);
responsiveShards = results[2].filter(responsive => responsive).length;
})
.catch(error => {
console.error(new Date(), `Error fetching shard data:`, error);
});
d.js docs
d.js docs3w ago
:mdn: Promise.resolve() The Promise.resolve() static method "resolves" a given value to a Promise. If the value is a promise, that promise is returned; if the value is a thenable, Promise.resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.
Iced Queen
Iced Queen3w ago
I had the same problem before using that. Someone else recommended it to me, although I don't remember where You asked if it was a flaw in my code, so I sent the code. If I knew if there was a flaw, it wouldn't be there 😅 I do not think any shards go offline, as the total shards and responsiveShards are the same But how could that be? It shows the correct counts but after X hours of running it doesn't. Exactly the same thing the OP said?
Iced Queen
Iced Queen3w ago
No description
Iced Queen
Iced Queen3w ago
This post is about two issues where I have one of them as well. They just titled it after the first issue Ah yeah, now I get it, sorry 😅
Want results from more Discord servers?
Add your server