Errors
Every error type the API can return, with its cause and its fix.
Error format
Every error is JSON with a type, sometimes with more fields:
{ "type": "MissingPermission", "permission": "ManageMessages" }
{ "type": "FailedValidation", "error": "content: length must be between 0 and 2000" }
{ "type": "FileTooLarge", "max": 20000000 }Branch on type, never on the text. Types are stable: they are never renamed or removed. New ones can appear in newer servers, so treat an unknown type as a general failure.
What to do with an error
| Status | Meaning | What to do |
|---|---|---|
400, 422 | The request is wrong | Fix it. The same request fails again |
401 | The token is wrong | Stop the bot and check the token |
403 | The bot may not do this | Tell the person. Do not retry |
404 | It is gone | Forget it |
409 | A conflict | Fetch the current state |
429 | Too many requests | See Rate limits |
5xx | Our side failed | Retry with a growing delay, three to five times |
Errors raised by the web server itself (no token, unknown route, a body that is not JSON) are JSON too. Check the status before you parse a body, because a proxy in between can still answer with HTML.
Is the bot in that server?
A bot sees only the servers it was installed in. For a server it is not in, the answers differ by route:
| Call | Answer |
|---|---|
GET /servers/{target} | 404 NotFound |
GET /channels/{target} for one of its channels | 404 NotFound |
POST /channels/{target}/messages for one of its channels | 403 MissingPermission |
So a 403 MissingPermission when your bot writes to a channel id someone gave it can mean that the bot is not installed there. Ask GET /channels/{target}: 404 NotFound means the bot is not in that server (or the channel does not exist), so install the bot first, with the invite link from the Developer Portal. A 403 MissingPermission there means the bot is in the server and cannot see the channel: a private channel needs View Channel for one of the bot's roles.
Errors a bot can get
| Type | HTTP | Cause | Fix |
|---|---|---|---|
UnknownUser | 404 | The user does not exist or the bot cannot see them. | Check the id. The person may have deleted their account. |
DirectMessagesRestricted | 403 | The person's privacy settings refuse this DM. | Do not retry. Reach them in a server channel. |
DirectMessagesPaused | 403 | The server paused DMs between its members. | Do not retry. A moderator lifts the pause. |
BlockedByOther | 403 | The person blocked the bot. | Do not retry. |
OfficialAccount | 403 | An official Zrzur account cannot be replied to, reacted to, pinned or reported. | Do not retry. |
UnknownChannel | 404 | The channel is gone or the bot cannot see it. | Check the id and that the bot has View Channel. |
UnknownMessage | 404 | The message is gone, or it is not in this channel. | Treat it as deleted. |
UnknownAttachment | 400 | A file id in the body does not exist or was already used. | Upload the file again. Each upload can be used once. |
CannotDeleteMessage | 403 | The message cannot be deleted, for example one this interaction did not create. | Delete only what your bot wrote, or get Manage Messages. |
CannotEditMessage | 403 | A bot can only edit its own messages. | Send a new message instead. |
CannotJoinCall | 400 | The channel takes no calls. | Use a voice channel. |
TooManyAttachments | 400 | The message has more files than max. | Send the files in several messages. |
TooManyEmbeds | 400 | The message has more embeds than max. | Send fewer embeds. |
TooManyReplies | 400 | The message replies to more messages than max. | Reply to fewer messages. |
TooManyChannels | 400 | The server reached its channel limit, max. | Delete a channel first. |
TooManyChannelWebhooks | 400 | The channel reached its limit of webhooks. | Delete a webhook in this channel. |
TooManyServerWebhooks | 400 | The server reached its limit of webhooks. | Delete a webhook in this server. |
RateLimited | 429 | A webhook sent too much. The body has retry_after in milliseconds. | Wait that long, then send again. |
ForumThreadRequired | 400 | A webhook posted to a forum without a thread. | Send thread_id, or thread_name to start one. |
ThreadsDisabled | 403 | The server switched threads off. What exists stays readable. | Do not retry. Only the server can switch them back on. |
ForumsDisabled | 403 | The server switched forums off. What exists stays readable. | Do not retry. Only the server can switch them back on. |
PluginsDisabled | 403 | Plugins are switched off on this server. No plugin route answers while they are off. | Do not retry. Plugins come back only when the server turns them on. |
EmptyMessage | 422 | The message has no content, embeds, attachments or components. | Send something. |
PayloadTooLarge | 422 | The message is over a size limit. | Shorten the text or the embeds. |
AlreadyPinned | 400 | The message is already pinned. | Ignore it. |
NotPinned | 400 | The message is not pinned. | Ignore it. |
InSlowmode | 429 | The channel has slowmode and the bot wrote too soon. The body has retry_after. | Wait, or give the bot Bypass Slowmode. This is a refusal, not a rate limit. |
UnknownServer | 404 | The server does not exist or the bot is not in it. | Check the id. Forget a server when you get ServerDelete. |
InvalidRole | 404 | The role does not exist in this server. | Fetch the roles again. |
Banned | 403 | This user is banned from the server. | A moderator removes the ban first. |
AlreadyInServer | 409 | The bot is already in this server. | Nothing to do. |
CannotTimeoutYourself | 400 | The target of the timeout is the bot itself. | Pick another member. |
TooManyEmoji | 400 | The server reached its emoji limit, max. | Delete an emoji first. |
TooManyRoles | 400 | The server reached its role limit, max. | Delete a role first. |
UnknownApplication | 404 | The application does not exist. | Check the id: an application id is the bot's user id. |
ApplicationNotInstalled | 403 | Someone used a bot that is not in this server. | Install the bot in the server. |
ApplicationOffline | 503 | The bot was suspended or switched off, so it receives nothing. | Its owner contacts Zrzur support. |
SignedDeliveryRejected | 400 | Your HTTP interaction address failed its test. reason says why. | See Interactions over HTTP. |
UnknownCommand | 404 | The command id is unknown, or it was deleted. | Fetch the command list. |
CommandAlreadyExists | 409 | A command with this name and type already exists in this scope. | Use PUT to replace the list, or edit the command. |
TooManyCommands | 400 | The limit of max commands of this type in one scope is reached. | Delete commands first. |
UnknownInteraction | 404 | The interaction id or token is wrong. | Use the values from InteractionCreate as they are. |
InteractionExpired | 410 | The 3 seconds to acknowledge, or the 15 minutes of the token, are over. | Acknowledge sooner. Use DeferredMessage for slow work. |
InteractionAlreadyAcknowledged | 409 | This interaction already has its first answer. | Use a follow-up, or edit the original. |
TooManyFollowups | 400 | The limit of max follow-ups for one interaction is reached. | Edit a message, or send a normal message. |
IsBot | 400 | This route is for people. Bots are refused. | Do it another way. The reference marks what bots can use. |
BotIsPrivate | 403 | Only the owner can install a private bot. | Sign in as the owner, or make the bot public. |
MissingPermission | 403 | The bot lacks the permission named in permission. | Give the bot that permission, or tell the person. |
MissingUserPermission | 403 | The person the bot acts for lacks the permission in permission. | Tell the person. |
MissingIntent | 403 | The route or connection needs the intent named in intent. | Switch it on in the Developer Portal and ask for it when you connect. |
MasqueradeNameTaken | 400 | The masquerade name copies another member. | Choose another name. |
BotNeedsVerification | 403 | An unverified bot stops at 100 servers. | Ask for verification. |
VerificationRequired | 403 | The server's verification level refuses this member for now. requirement says why. | Wait, or ask the server's moderators. |
AutoModBlocked | 403 | The server's AutoMod rule rule refused the message. | Change the text. Do not retry the same text. |
RulesNotAccepted | 403 | The member has not accepted the server's rules. | Tell them to accept the rules. |
InvitesPaused | 403 | The server paused invites. | Do not retry. A moderator lifts the pause. |
NotElevated | 403 | The target ranks at or above the bot, or the role is above the bot's top role. | Move the bot's role higher. |
NotPrivileged | 403 | The bot's rank is too low for this change. | Move the bot's role higher. |
CannotGiveMissingPermissions | 403 | The bot tried to give a permission it does not have itself. | Give the bot that permission first. |
NotOwner | 403 | Only the owner can do this. | Ask the owner. |
IsElevated | 403 | The target ranks too high for this. | Pick a lower target. |
InternalError | 500 | Something failed on the server. | Wait and retry with a growing delay. Report it if it stays. |
InvalidOperation | 400 | The request is not valid in this state, for example a Modal as the answer to a form. | Check the rules of this route. |
InvalidCredentials | 401 | The token, password or ticket is wrong. | Check it. |
InvalidProperty | 400 | A field combination is not allowed here. | Check the request body. |
InvalidSession | 401 | The token is missing or wrong, or the bot was suspended. | Stop and check the token. Retrying does not help. |
NotAuthenticated | 401 | The route needs a token and got none. | Send x-bot-token. |
DuplicateNonce | 409 | The same nonce was used for a different request. | Use a new value for each new message. |
NotFound | 404 | The route or the object does not exist. | Check the path and the ids. |
NoEffect | 400 | The request changes nothing. | Ignore it. |
FailedValidation | 400 | The body breaks a limit or a rule. error says which in one line, and fields lists each field with its rule. | Fix the body. Do not retry the same request. |
LiveKitUnavailable | 400 | Voice is not available on this server. | Try again later. |
NotAVoiceChannel | 400 | The channel is not a voice channel. | Use a voice channel. |
AlreadyConnected | 400 | The bot is already in this voice channel. | Disconnect first. |
NotConnected | 400 | The member is not in a voice channel. | Check the voice states first. |
UnknownNode | 400 | The voice node does not exist. | Take a name from features.livekit.nodes of GET /. |
FeatureDisabled | 400 | This server has the feature named in feature switched off. | Do not retry. Self-hosted servers switch it on in their configuration. |
HeaderTooLarge | 400 | A header is too large, for example the audit log reason. | Shorten it. |
ProxyError | 400 | The link or media proxy could not fetch the address. | Check that the address is public. |
FileTooSmall | 422 | The uploaded file is empty. | Send a file with content. |
FileTooLarge | 422 | The file is over the limit of its tag, max. | Send a smaller file. |
FileTypeNotAllowed | 400 | This tag takes images only. | Send an image, or use attachments. |
ImageProcessingFailed | 500 | The image could not be read. | Send a valid image. |
NoEmbedData | 400 | The link has no preview data. | Ignore it. |
MissingHeaders | 400 | A required header is missing. | Send x-bot-token, and content-type with a body. |
OperationFailed | 500 | The action could not finish. | Retry once, later. |
IncorrectData | 400 | The stored data does not match. with names it. | Fetch the object again. |
DatabaseError | 500 | A database call failed on the server. | Wait and retry with a growing delay. |
VosoUnavailable | 400 | The old voice service is unavailable. | Use LiveKit voice. |
RenderFail | 500 | The server could not render a template. | Retry later. |
LabelMe | 500 | An unlabelled server error. | Retry later. Report it if it stays. |
ContactSupport | 400 | The server wants a person to contact support. msg says why. | Show the message to the owner. |
InvalidFlagValue | 400 | A flag has a value the server does not know. | Check the flags. |
TooManySounds | 400 | The server's soundboard is full. | Remove a sound first. max is the limit. |
SoundAlreadyAdded | 409 | This library sound is on the server's soundboard already. | Nothing to do. |
SoundLibraryUnavailable | 503 | The sound library is not ready yet. | Try again in a minute. |
TooManySpeakers | 400 | The stage has as many speakers as it may have. | Move a speaker back to the audience first. max is the limit. |
PollEnded | 409 | The poll is over: no more votes, and it cannot be ended again. | Do not retry. |
Errors of account routes
Bots rarely see these. They belong to routes for people, such as signing in.
| Type | HTTP | Cause | Fix |
|---|---|---|---|
AlreadyOnboarded | 403 | The account already has a username. | Used by the app only. |
AgeNotDeclared | 403 | The account has not declared its age. | People only: finish it in the app. |
UsernameTaken | 409 | The username is taken. | Choose another name. |
InvalidUsername | 400 | The username has characters that are not allowed. | Use letters, digits, ., - and _. |
DiscriminatorChangeRatelimited | 429 | The name tag changed too recently. | Wait. |
AlreadyFriends | 409 | The users are friends already. | Bots have no friends. |
AlreadySentRequest | 409 | A friend request is pending. | Bots have no friends. |
Blocked | 409 | The user is blocked. | People only. |
NotFriends | 403 | This needs a friendship. | Bots have no friends. |
GroupInvitesRestricted | 403 | The person refuses group invites. | People only. |
TooManyPendingFriendRequests | 400 | Too many friend requests are pending. | People only. |
CannotRemoveYourself | 400 | The group owner cannot remove themselves. | People only. |
GroupTooLarge | 403 | The group is full. | People only. |
AlreadyInGroup | 409 | The user is already in the group. | People only. |
NotInGroup | 404 | The user is not in the group. | People only. |
CantCreateServers | 403 | This account cannot create servers. Bots never can. | Create the server as a person. |
TooManyServers | 400 | The account reached its server limit. | Leave a server first. |
VanityUnavailable | 403 | The server cannot have a custom address. | People only. |
VanityTaken | 409 | The custom address is taken. | Choose another one. |
VanityReserved | 400 | The custom address is reserved. | Choose another one. |
VanityPaused | 410 | The custom address is paused. | Ask support. |
TooManyCommunityItems | 400 | The creator reached the limit of items. | Not for bots. |
MissingPlatformPermission | 403 | This needs a Zrzur staff permission. | Not for bots. |
ProfileTextFiltered | 422 | The platform word list stopped this text. | Not for bots. |
CommunityItemConflict | 409 | The gallery item changed meanwhile. | Not for bots. |
TooManyReports | 429 | Too many reports in a short time. | Wait. |
SafetyCaseConflict | 409 | The safety case changed meanwhile. | Not for bots. |
TooManySupercharges | 400 | The limit of Wings is reached. | Not for bots. |
TooManyBotCreations | 429 | The account made 7 bots in the last 7 days. | Wait until resets_at, then create the bot. |
PromotionSlotsFull | 409 | All promotion slots are taken. | Not for bots. |
NotOnDiscover | 400 | The server is not on Discover. | Not for bots. |
ReachedMaximumBots | 400 | The account reached its limit of bots. | Delete an old bot first. |
IsNotBot | 400 | This route is for bots. | Send x-bot-token. |
CannotReportYourself | 400 | People cannot report themselves. | Not for bots. |
CaptchaFailed | 400 | The captcha failed. | People only. |
BlockedByShield | 400 | The sign-up shield refused the request. | People only. |
UnverifiedAccount | 403 | The account's e-mail is not verified. | Verify the e-mail. |
EmailFailed | 500 | The e-mail could not be sent. | Try again later. |
InvalidToken | 401 | The link or code is wrong or has expired. | Ask for a new one. |
MissingInvite | 400 | This server needs an invite to sign up. | People only. |
InvalidInvite | 400 | The invite is wrong. | Ask for a new one. |
CompromisedPassword | 400 | The password is on a list of leaked passwords. | Choose another one. |
ShortPassword | 400 | The password is too short. | Choose a longer one. |
LockedOut | 403 | Too many failed sign-ins. | Wait. |
TotpAlreadyEnabled | 400 | The authenticator is already on. | People only. |
DisallowedMFAMethod | 400 | This check is not allowed here. | People only. |
AgeRequirementNotMet | 403 | The account is too young for this. | People only. |
AgeChangeNotAllowed | 403 | The age cannot be changed. | People only. |
AgeRestricted | 403 | The content is limited by age. | People only. |
TooManyServerEvents | 400 | The server has as many scheduled events as it may have. | People only. |
ForwardMatureContent | 403 | A message from a mature channel can only be forwarded into another mature channel. | People only: bots cannot forward. |
OAuth2 errors
POST /oauth2/token follows the OAuth2 standard and answers with error and error_description instead of type. See OAuth2.