Skip to main content
Every message of ChapterJS says what happened, then what to do. This page gathers them, with the symbol you see in front:
The commands, variables and exit codes are in the CLI reference.

Before connecting

chapterjs dev needs BOT_TOKEN and DEV_GUILD_ID. Copy .env.example to .env and fill them in: see Your Discord application.
Copy the token from the Developer Portal: your application → Bot → Reset Token. A token is only shown once, and resetting it makes the old one invalid everywhere it was used. The message says Environment: instead of .env: when the value came from the environment and not from the file.
The value was cut, or something was pasted with it. Copy the token again from the Developer Portal, in one piece. A Bot in front of it is fine: it is removed.
In Discord, right-click your test server → Copy Server ID. If you don’t see it, enable Settings → Advanced → Developer Mode.
A server ID is a number of 17 to 20 digits: not the name of the server, not an invite link. Copy it again: right-click your test server → Copy Server ID. In production, where it is optional, you can also remove it.
chapterjs start found no .env file and no BOT_TOKEN in the environment. On a host, give BOT_TOKEN in its settings (often called “environment variables” or “secrets”), or put it in a .env file next to package.json. The environment wins when both are there.
Run the command in the folder of your bot, the one with package.json. To start a project, run pnpm create chapterjs.
The token is not the one of your bot any more, usually because it was reset. Copy it again from the Developer Portal into BOT_TOKEN. Nothing can work until it is fixed, so the command stops.
The request never reached Discord, or Discord kept failing. Check your internet connection and discordstatus.com, then start again.
Discord answered one of the first requests with an error the framework did not expect. The rest of the line is Discord’s own message. Check the token and the ID of your test server, then start again; if it keeps happening, open an issue with the message.
The message gives you a link: open it and confirm. In a terminal, chapterjs dev waits (Waiting for the bot to be added...) and goes on by itself with ✓ The bot joined …. If the link shows another server, DEV_GUILD_ID is not the ID of a server you manage. Started by another program, the same message is a ✗ and the command stops.
One of your files needs a privileged intent: Message Content Intent for messageCreate and messageUpdate, Server Members Intent for memberJoin, memberLeave, memberUpdate, threadMemberJoin and threadMemberLeave, Presence Intent for presenceUpdate. The message lists the files that need each one and gives the link to the right page: enable the option under Privileged Gateway Intents, then save. In a terminal, chapterjs dev waits (Waiting for you to enable it...) and goes on with ✓ Privileged intents enabled. Started by another program, and always with chapterjs start, the same message is a ✗ and the command stops. See Privileged intents.
Discord closed the connection because of a privileged intent, although the check before connecting passed: the option was disabled while the bot ran, or the application was changed in the meantime. Enable it in the Developer Portal (your application → Bot → Privileged Gateway Intents) and start again.
Discord limits how many times a day a bot can connect, and resets the token of a bot that goes over. ChapterJS stops before that. It usually means the bot was restarted too many times: look for what makes it stop, then start it again after the time given in the message.
Discord refused a connection that carries too many servers. ChapterJS asks Discord how many connections to open before connecting, so start the bot again; if it keeps happening, open an issue.
Discord refused something the framework computed by itself. Start the bot again; if it keeps happening, open an issue with the message.
Update the chapterjs package of your project, then build and start again.
Discord ended the connection for a reason reconnecting can’t fix, and gave a code the framework has no words for. Start again; if it keeps happening, open an issue with the code.
Your src/ declares no command and no event. The bot still connects. Declare one: see Project structure.

While your bot runs

A file you saved can’t run: the first line names it, with the line and what is wrong. Your bot is still online with the last version of that file that worked. Fix the file and save: it reloads. A file that never worked is left out until it does.
One of your functions threw: the line names the file and the line in your code, and the rest is the error. Nothing else stops. For a command, the person got a short private answer. See when your function fails.
One of your functions called something that answers later (a store, a reply, a request) without await, and it failed with nobody to tell. Without this line, Node would have stopped the bot; instead the error is reported with your file and line, and the bot keeps running. Write await in front of the call and async before run, so that your function waits for it and its errors are reported with it.
A file you added listens to something the connection was not asked for (a new event, a file that now listens to private messages). ChapterJS reconnects by itself with what is needed and says ✓ Reconnected, … loaded; if that needs a privileged intent, see above.
chapterjs dev only runs your bot in your test server, so a command or an event of private messages only can’t be tried there. It works with chapterjs start.
You are changing a command that is already online for everyone. Your test server shows both until production runs your version. A second application for development never shows that: see A second bot for development.
Discord did not accept what your commands declare (a name, a description, an option…): the rest of the line is Discord’s own message, with the field it refused. The bot keeps running with the commands Discord already has. Fix the file and save.
Nothing to do: the bot reconnects by itself, and tells you with ↻ Reconnected to Discord. Your files keep running.
Your run function returned without calling interaction.reply(). Every command must answer: see Answering.
The command was used somewhere the bot can’t send a message (a kind of channel it does not handle, or a place Discord did not describe). The person read “This command can not be used here.” and your function did not run.
An event happened in a channel the bot does not know yet (a thread it never saw, for example), and Discord refused to describe it: the bot lacks the permission to see that channel. Your files did not run for that event. Give the bot access to the channel if it should react there.
The event only gave the id of who did it (a reaction removed, a vote, someone interested in a scheduled event), the bot did not know that person, and Discord refused to describe them: usually an account that was deleted. Your files did not run for that event. Nothing to do.
On a stage, the bot is in the audience until it may speak. Accept its request in Discord, or give it Mute Members so it becomes a speaker by itself.
Discord ended the voice connection for the reason given; voice.connected is now false. Join again; if it keeps happening, open an issue with the message.
The bot received an update of the encryption of the call it could not use, and asked Discord to add it again. Nothing to do: it is back in a moment, and what it plays meanwhile is not heard.
The voice server could not be reached again after a change of server. Join again.
Something in an event sent by Discord could not be applied to what the bot remembers. Your files still received the event. If it keeps happening, open an issue with the message.
A newer version of the package is published. Run the command of the second line (it is the one of your package manager), then start chapterjs dev again. The third line links to what changed. Nothing is installed by itself.
The bot remembers fewer members per server, and your code works the same. Nothing to do: see Memory. When memory is fine again, ℹ Memory is fine again: the bot remembers up to … members per server again. says so.
The message says how much remembering less freed. Little: look in your own code for something that only grows (a list, a Map you add to and never empty). A lot, and it is still full: your bot is large; give it more memory with NODE_OPTIONS=--max-old-space-size=4096 (in MB) on a machine that has that much. See Memory.
One of the processes of a large bot exited. It is started again by itself: at once when it had run for more than a minute, after a growing delay otherwise. Look at the lines starting with [N] just before to see why it stopped.
Please open an issue with the message. The command stops.

Building and starting

The lines below are what your editor underlines. Fix them, or find them all at once with the typecheck script of your project. The build never ships a file that does not type-check.
The build goes on without checking the types. To check them where you build, install the development dependencies of your project too, and keep the tsconfig.json of the template.
The lines above name each file and what is wrong, as chapterjs dev does when you save it. Fix them and build again. can't be compiled is a file the compiler could not read; can't run once compiled is a file that runs from src/ but not in the compiled bot.
chapterjs start runs what chapterjs build prepared, and nothing else. Run the build script first, on the same machine or before uploading .chapterjs/build.
The version of ChapterJS changed since the build. Run chapterjs build again.
In production, saving a file changes nothing until you build again. Run chapterjs build, then start again.
The build ran when it was made; something changed around it since (a package, the version of Node). Run chapterjs build again: it says what to fix.
A file of the build no longer passes the checks it passed when built. Run chapterjs build again: it says what to fix.
chapterjs start only takes --processes with a whole number of 1 or more. With a package manager, put -- before the option when it needs it: npm run start -- --processes 4.
The chapterjs CLI has five commands: dev, build, start, test and sync. The usage printed below the message lists them.

Testing

The lines above name each file and what is wrong, as chapterjs dev does when you save it. Nothing is tested until every file runs: fix them and test again.
One of your functions threw, or finished without answering, while it was used by itself with ordinary and hard values. Each line below names the case (a text at its longest, a number at zero, someone who left…) and the file and the line of what threw. See What is checked by itself.
Every file was checked once, and your project has no scenario to run. Nothing is wrong: write one when you want to check what the bot answers. See Scenarios.
A check of that scenario failed, or a function of the bot threw while it ran. The line below gives the file and the line of your scenario, what was expected and what came.
A *.test.ts file exports nothing made with scenario(). The bot never loads these files, so what is in it runs nowhere: export a scenario, or rename the file.
A scenario ran out of time. Usually a bot.use() or a bot.click() waits for a function that never answers, or a cooldown refuses the second use: time does not pass in the test server.

What people see on Discord

Your run function finished without calling interaction.reply(). chapterjs dev warns you (⚠ … finished without answering). Every command must answer: see Answering.
Someone clicked a button or a select menu, or sent a form, and its run finished without answering. chapterjs dev warns you (⚠ … finished without answering). Answer with interaction.update(), interaction.reply(), or interaction.deferUpdate() to change nothing: see Buttons.
The message is older than your project: the export of the component was renamed or removed since the message was sent (moving its file changes nothing). Send the message again, or bring the export back.
The data of the component changed shape since the message was sent (a value added, removed or of another kind). Old messages carry the old data: send the message again.
A task took longer than the time between two of its runs. The next run waits for its turn; make the task faster, or run it less often.
A task was due while the bot was reconnecting to Discord. It runs again at its next time.
The component says who: 'author', and someone else clicked. That is what you asked for: see Who may click.
Your run function threw. The person gets this short answer, privately; you get the error with the file and the line in your terminal. When Discord refused an action for a missing permission, the person reads “I don’t have the permission to do that here.” instead.
The command was used where it does not work: a command of servers in a private message, a command of private messages in a server, or a place the bot can’t answer in. The first two come from where in the file: see Servers and private messages.
The person lacks a permission the command asks for with permissions, where they used it. See Who can use a command.
The command has a cooldown, and the person used it too soon. That is what you asked for: see Cooldowns. The answer deletes itself when the cooldown ends; past 15 minutes it shows the date and time instead.
The phrases the bot answers by itself can be translated in the language files of the project: see What the bot answers by itself.
Commands appear at once in your test server with chapterjs dev, and everywhere with chapterjs start. If one is missing, the terminal said why when it started: a name Discord refused, or two files that are the same command. Shown twice: see One bot for dev and production. A command the person can’t see is one whose permissions they don’t have: see Who can use a command.
Press Ctrl+C once and let it disconnect: you see ✓ Disconnected and the bot goes offline at once. A second Ctrl+C stops the process without waiting, and Discord then keeps the bot online until it notices the connection is gone.