Why does my Discord bot keep going offline or crash looping?
Stop a Discord bot from crashing or restarting in a loop: catch unhandled errors, fix memory limits and avoid hitting Discord's session start limit.
Updated · 2 min read
A bot goes offline when its process exits. Schokr servers don't sleep when idle, so if your bot keeps dropping, something is making the process stop: an uncaught error, running out of memory, or a login problem. The console output right before it stops tells you which.
Step 1: read the last lines in the console
Open your server's console and look at the output just before the server stopped. See reading bot logs. Then match it to a cause below.
| What you see | Likely cause |
|---|---|
| A stack trace, then the process exits | Unhandled error or promise rejection |
| No error, the server just stops while memory is near the limit | Out of memory |
TokenInvalid or LoginFailure | Bad token. See invalid token errors |
Used disallowed intents or PrivilegedIntentsRequired | See privileged intents |
Cannot find module or ModuleNotFoundError | See module not found errors |
Unhandled errors in discord.js
Since Node.js 15, an unhandled promise rejection crashes the whole process. One failed reply() (for example, Missing Permissions) can take your bot down. Catch errors where they happen, and add a safety net:
process.on('unhandledRejection', (reason) => {
console.error('Unhandled rejection:', reason);
});
process.on('uncaughtException', (error) => {
console.error('Uncaught exception:', error);
});
client.on('error', (error) => console.error('Client error:', error));
Wrap command handlers too:
client.on(Events.InteractionCreate, async (interaction) => {
try {
await handleCommand(interaction);
} catch (error) {
console.error(error);
if (interaction.isRepliable() && !interaction.replied && !interaction.deferred) {
// MessageFlags is imported from discord.js
await interaction.reply({ content: 'Something went wrong.', flags: MessageFlags.Ephemeral }).catch(() => {});
}
}
});
The global handlers are a safety net, not a fix. Log the error and fix the code that throws it.
Errors in discord.py
discord.py catches errors inside commands and events and logs them without exiting, so a Python bot usually stays online. It can still stop if:
- Code runs before
bot.run()and raises (bad import, missing env variable). - A
tasks.loopraises: the loop stops silently while the bot stays up. Add anerrorhandler to the loop. - You call blocking code (like
time.sleeporrequests) inside async handlers. The heartbeat is blocked and Discord disconnects the bot. Useasyncio.sleepand an async HTTP library such asaiohttp.
Add a global command error handler so you see problems:
@bot.event
async def on_command_error(ctx, error):
print(f"Command error in {ctx.command}: {error!r}", flush=True)
Out of memory
If the bot uses more memory than the server's limit, the process is killed with no error from your code. Check the Resources view. Either give the server more memory from your team's pool, or reduce usage; see reducing bot memory usage.
Don't let it restart endlessly
Every time a bot logs in it uses one "session start". Discord allows a limited number per day (1,000 for most bots). If a crash loop burns through them, Discord terminates the bot's sessions and resets its token, and you'll get an email about it. If your bot is crash looping, stop the server, fix the cause, then start it again.
Bot shows offline but the server is running
- The process is stuck before login (for example, waiting on a database connection). Add a log line before
login()/run(). - A second copy elsewhere is using the same token. Stop any local copies.
- Check status.schokr.gg and Discord's own status page for outages.
Still stuck?
Share the last 30 or so console lines (token removed) in the Schokr Discord.