Discord bot online but not responding to commands

An online bot that ignores commands usually lacks the Message Content intent, has unregistered slash commands or lacks channel permissions. Check the log and the Bot page in the Developer Portal.

Updated 5 min read

Learning objectives

After reading this article you will be able to:

  • Tell prefix bots (messages) apart from slash command bots (interactions)
  • Diagnose intents, command registration, permissions and the 3-second deadline
  • Fix each cause with current discord.js v14 code
On this page

The bot shows a green dot, but you type the command and nothing happens. That is different from a bot that is offline: the Gateway connection exists, and the problem is what the bot receives, what it is allowed to do, or how long it takes to answer.

One question drives the whole diagnosis: is your command a prefixed message (!ping) or a slash command (/ping)? They use different events and break for different reasons.

Online but silentPrefix!pingSlash/pingMessage Contentintentwithout it, content is emptyturn it on in Portal and code1Command registeredthrough the HTTP API (PUT)2Invite scopeapplications.commands3Reply within 3 sor deferReply() firstBoth: permission in the channel (50013, 50001)
Prefix depends on the Message Content intent; slash depends on registration, scope and a 3 s reply. Permissions apply to both.

How do you know the bot receives the event?#

Before suspecting intents or permissions, prove the event arrives. A console.log on the first line of the handler separates "the bot never gets it" from "it gets it and fails later".

js
import { Client, Events, GatewayIntentBits } from "discord.js";

const client = new Client({
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
});

client.on(Events.MessageCreate, (m) => console.log("msg:", JSON.stringify(m.content)));
client.on(Events.InteractionCreate, (i) => console.log("interaction:", i.type, i.commandName));

client.login(process.env.DISCORD_TOKEN);

If msg: prints "" (empty) for messages that clearly have text, the cause is the content intent. If nothing prints for a slash command, the problem is registration or scope. If it prints and the user still sees no reply, the problem is permissions, a handler error or timing.

Why does a prefix bot ignore messages?#

This is the most common cause. Without the privileged Message Content intent (value 1 << 15, 32768), Discord delivers content, embeds, attachments, components and poll as empty values. The exceptions are the bot's own messages, DMs with the bot, messages that mention the bot, and the target message of a message context menu command.

That is why message.content.startsWith("!") is never true: the bot gets the event but not the text. Fix it in two places:

  1. In the Developer Portal, on the Bot page, turn on Message Content Intent. Unverified apps can enable it directly. Verification is required at 100 or more servers, and then the intent must also be approved.
  2. In code, declare the intent:
js
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});

If you declare the intent in code without enabling it in the portal, the Gateway closes the connection with code 4014 (the bot goes offline, not silent). More in Discord bot intents errors. If your bot only needs commands, moving to slash commands removes the dependency on this intent.

Why is the slash command missing or doing nothing?#

Running your bot code does not create slash commands. They must be registered through the HTTP API: PUT /applications/{id}/commands for global commands, PUT /applications/{id}/guilds/{guild_id}/commands for one server. If you only wrote the handler, Discord does not know the command exists.

Checklist:

  • Did you register it? Guild commands update instantly, so use them for testing. Use global commands for production.
  • Was the bot invited with the right scope? Creating commands in a server requires the applications.commands scope. The bot scope includes it, but an invite made only with other scopes does not.
  • Right server? A command registered in one server does not exist in others or in DMs.
  • Limits: 100 global CHAT_INPUT commands, and 200 command creates per day, per guild. Instead of recreating commands one by one, use bulk overwrite (PUT), which replaces the whole list (omitted commands are removed).

Why does it say "The application did not respond"?#

Discord requires an initial response to an interaction within 3 seconds. After that the token is invalidated and the user sees the failure. The same happens if the handler throws before replying. Querying a database, calling an external API or generating an image often blows past that deadline.

The fix is to acknowledge first and answer later:

js
import { MessageFlags } from "discord.js";

client.on(Events.InteractionCreate, async (interaction) => {
  if (!interaction.isChatInputCommand()) return;
  if (interaction.commandName !== "report") return;

  try {
    await interaction.deferReply(); // acknowledges in under 3 s, user sees "thinking..."
    const text = await buildReport(); // can take a while
    await interaction.editReply(text); // the token lasts 15 minutes
  } catch (err) {
    console.error(err);
    if (interaction.deferred || interaction.replied) {
      await interaction.editReply("Something went wrong.");
    } else {
      await interaction.reply({ content: "Something went wrong.", flags: MessageFlags.Ephemeral });
    }
  }
});

The interaction token is valid for 15 minutes for editReply and followUp. Two related errors show up in logs: 10062 Unknown interaction (the interaction expired) and 40060 Interaction has already been acknowledged (you replied twice; use followUp or editReply for the second one).

Does the bot have permission to answer in that channel?#

If the event arrives and the code runs without errors but nothing appears, the bot may lack permission to send. The log shows:

text
DiscordAPIError[50013]: Missing Permissions
DiscordAPIError[50001]: Missing Access

50013 means a missing permission for the action (for example Send Messages or Embed Links) and 50001 means no access to the channel (View Channel). The usual cause is a permission override on the channel or category that overrides the bot's role. Test with the bot's role set to Administrator in a test server: if it starts working, it is a permission problem, and you then grant only what is needed. Do not leave Administrator on in production.

What if the handler fails silently?#

In async code, an exception without try/catch becomes an unhandled promise rejection. On current Node.js versions that crashes the process by default, and if a wrapper swallows it, the error never shows up at all. Add process.on("unhandledRejection", console.error) and handle errors in the handler as in the example above. Also check rate limits: a loop that sends too many messages gets 429 and goes quiet for a few seconds, covered in Discord 429 rate limit errors.

Finally, code changes only apply after the process restarts. If you edited the handler and nothing changed, confirm the new version is the one running.

How to do this on Square Cloud#

To debug a silent bot, what you need most is a live log. On Square Cloud it appears in the dashboard, the CLI, the VS Code extension and the mobile app, so you can add the console.log lines above, restart and see the result right away.

The token lives in the application's environment variables (dashboard, API, CLI or VS Code), and a change applies on the next restart, with no rebuild. You can host bots built with discord.js, discord.py, JDA, Discord.Net or any Gateway library. Each background application, such as a bot, reserves at least 256 MB from the plan's RAM pool.

See the Discord bot hosting page for details and plans.

Bot hosting

Keep your bot online 24/7 with automatic restarts

Learn more

FAQs

Why is my bot online but ignoring !commands?

Message content is a privileged intent. Without Message Content enabled in the Developer Portal and declared in code, the content field arrives empty and your prefix never matches.

What does 'The application did not respond' mean on a slash command?

Discord requires an initial response within 3 seconds. If your handler takes longer, or throws before replying, the user sees that failure. Call deferReply() to buy time.

My new slash command does not show up. What now?

Commands exist only after you register them through the API (PUT on /applications/{id}/commands). Register them as guild commands while testing, since those update instantly, and make sure the bot was invited with the applications.commands scope.

The bot works in my test server but not in others. Why?

Usually permissions: the bot needs View Channel and Send Messages in the channel, and a role or channel override may deny them. Also check whether the command was registered only in that one server.

Next articleDiscord bot token: where to find it and how to keep it safeA Discord bot token lives on the Bot tab of the Developer Portal and works as the bot's password. Learn where to find it, how to store it and what to do if it leaks.