Moderation
Ban, kick, timeout, mute, jail, warn: the punishment commands, the hierarchy rules behind them, and what happens on rejoin.
The punishment commands share the same shape: a target, an optional duration, an optional reason, and a set of guards that run before anything actually happens to that member. Two ideas run through all of them and are worth understanding once rather than re-deriving from each command's behaviour: hierarchy is checked separately from permission, and undoing a punishment is deliberately easier than applying one.
Punish a member
Syntax
,ban <person> [purge-window] [reason] [-s]
Example
,ban @user 24h spamming invites
Syntax
,kick <person> [reason] [-s]
Example
,kick @user being difficult
Syntax
,timeout <person> <time> <reason>
Example
,timeout @user 4h cool off
Syntax
,mute <person> [time] [reason] [-s]
Example
,mute @user 1h spamming links
Syntax
,jail <person> [time] [reason] [-s]
Example
,jail @user 30m needs a timeout
Syntax
,warn <person> [reason]
Example
,warn @user watch the language
Syntax
,hackban <id> [purge-window] [reason]
Example
,hackban 123456789012345678 ban evasion
-s (or -silent) on ban, kick, mute and jail skips the DM notification the target would otherwise
get. Mute and jail need their mute role and jail role (and jail also needs its jail
channel) configured before either will fire: ,setup creates both roles and the channel for you.
Hackban bans by ID without requiring the target to be in the server, for banning known bad actors
before they join. If the ID you give is a current member, hackban runs the identical hierarchy
check ,ban does against them: it isn't a way to route around that check for someone who's actually
present.
Why jail removes roles, and mute doesn't
Discord decides what a member can see in a channel by combining every role they hold, and an allow beats a deny. That's a problem for jail on its own, on a server with a verification system: a jailed member's Verified role still granted them View Channel everywhere Verified allows it, and the jail role alone could never out-vote that.
So ,jail doesn't try to out-vote it. It removes every other role the member has, everything the
bot is able to remove, leaving them holding only the jail role. That's what makes the jail channel
the only thing left for them to see on a server where some other role used to grant wider access.
,unjail gives those roles back, and so does a timed jail expiring on its own.
A few things worth knowing:
- Roles Discord won't let the bot touch are left alone: anything above the bot's own highest role, and anything Discord manages itself, like a bot's own role, an integration's role, or the Nitro booster role Discord assigns. Neither direction, jailing or releasing, can move those.
- A booster role Righteous itself created is removed and given back. That's deliberate: it's a role like any other for this purpose, not an exception.
- A role deleted while the member was jailed, or moved above the bot in the meantime, can't be
restored on
,unjail. The bot reports how many roles it actually gave back rather than claiming success regardless. - If there's no record of the jail (the member was jailed before this existed, or was already
unjailed),
,unjailstill removes the jail role, and says plainly that no roles were restored rather than implying it put something back.
,mute works differently, because muting doesn't need to hide an entire server: it needs one
permission denied in whichever channels it would otherwise be overridden in. Muting doesn't touch
any of the member's roles. Instead, wherever some other role of theirs would override the mute in a
specific channel, Righteous adds a permission restriction scoped to just that channel, usually a
handful at most and often none. ,unmute clears exactly those restrictions and nothing else, so a
separate ,cmute a moderator set by hand is left untouched.
Both are re-applied automatically if the member leaves and rejoins, not only when the punishment is first issued: a fresh Verified role on rejoin would otherwise undo either one immediately. For the same reason, nothing else hands a rejoining member their old roles back while a mute or jail is still owed: role history, level rewards and autorole are all skipped for a member who rejoins under an active punishment. See Autorole and verification for how that join order works.
Ban's purge window is positional, and only consumed when it looks like one
Syntax
,ban <person> <purge-window> [reason]
Example
,ban @user 7d ban evasion again
After the target, the next word is checked against the same duration grammar ,timeout uses (2h,
24h, 7d, capped at Discord's own 7-day ceiling). If it parses as a duration, that many days/hours
of the target's messages are deleted and the rest of the words become the reason. If it doesn't parse
(say a reason that happens to start with a number, like 7 days late again) nothing is consumed as
a purge window and the whole thing is read as the reason. A malformed duration-shaped token (8d,
over the 7-day cap) is refused outright rather than silently clamped or dropped.
Hierarchy is a second, separate check
A permission gate answers "may this person use this command at all": it says nothing about who they
point it at. Every punishment command here checks hierarchy independently, and every one of those
permission gates is fakeperm-grantable, which is exactly why the second check matters: a role holding
only a fake BAN_MEMBERS still can't ban someone who outranks them.
Two things about that check are easy to miss:
- The server owner is checked separately from role position. An owner with no special role sits at the bottom of the role list by Discord's own numbering, so a plain position comparison would miss them entirely. Every punishment command refuses a target who is the server owner outright, before it ever compares roles: the bot owner is the one exception.
- An unreadable role position fails closed. If the caller's own highest role can't be read for some reason, the command refuses rather than guessing: the whole point of the check is to stop an escalation, so "I couldn't verify" has to mean "no."
The bot's own role position is checked too: Righteous refuses to act on someone who currently outranks its own highest role, the same way a human moderator would be refused by Discord itself.
Undoing a punishment is easier, on purpose
Syntax
,unban <person> [reason]
Example
,unban @user appeal accepted
Syntax
,unmute <person> [reason]
Example
,unmute @user
Syntax
,untimeout <person> [reason]
Example
,untimeout @user
Syntax
,unjail <person> [reason]
Example
,unjail @user served their time
Only the destructive direction is gated with the full hierarchy check above. Giving something back
doesn't need the same protection a punishment does, so the un- commands either skip the hierarchy
check entirely or run a lighter version of it: the permission gate (BAN_MEMBERS, MANAGE_MESSAGES,
or MODERATE_MEMBERS, matching the punishment each undoes) still applies, but a moderator doesn't
additionally need to out-rank the person they're releasing.
Scoped channel mutes
Syntax
,cmute [all|#channel] <person>
Example
,cmute @user
Beyond the account-wide mute above, five commands strip one specific permission from a member in one
channel (or, with all, every text channel): ,cmute (send messages), ,imute (embed/attach
images), ,emute (external emojis), ,rmute (add reactions), and ,hmute (hides the channel
entirely: this one additionally needs MANAGE_CHANNELS, on top of the usual MANAGE_MESSAGES).
Each has a matching ,c/i/e/r/hunmute to restore the permission. All five follow the same hierarchy
rule as the punishment commands above: undoing one of these mutes doesn't require out-ranking the
target, applying one does.
On slash, these five pairs are consolidated into one command, /channelmute, with a group per
permission type and a mute/unmute leaf inside each (/channelmute channel mute,
/channelmute image unmute, and so on) rather than ten separate top-level slash commands.
Control the channel
Syntax
,lockdown [#channel] [time] [hide]
Example
,lockdown #general 30m
Syntax
,unlock [#channel]
Example
,unlock #general
Syntax
,slowmode <on|off> [time]
Example
,slowmode on 10s
Syntax
,channel <add|delete|rename|topic|nsfw> ...
Example
,channel rename #general general-chat
Syntax
,threads <create|delete|add|remove|archive|lock|...> ...
Example
,threads lock #support-thread
Syntax
,invites <clean|clear|leaderboards>
Example
,invites clean
Syntax
,disconnect <person>
Example
,disconnect @user
,lockdown (alias ,lock) also has all, restrict, unrestrict and list forms for locking
every non-restricted channel at once and keeping specific channels out of that sweep. Lockdown with a
duration schedules its own reversal the same way a timed mute does.
Bulk anti-raid sweeps skip bad targets, they don't abort
Syntax
/raid <ban|jail> <minutes> [reason]
Example
/raid ban 15 mass join spam
Sweeps every member who joined within the given window (1–60 minutes) and punishes them. If the caller doesn't outrank one of those recent joiners (a legitimately-added moderator or the server owner happening to be in the window) that member is skipped and counted, not treated as a reason to abort the whole sweep. The final report says how many were punished and how many were skipped for outranking, so nothing silently disappears from the numbers.
Rejoining doesn't pardon anything
Leaving a server is not a way out of a punishment. A member who was muted, jailed or timed out and leaves before it's served has it re-applied on rejoin: the bot strips their other roles and re-adds the jail role, restores the mute's per-channel restrictions, or re-applies the timeout, the moment they come back. The one exception is a punishment whose duration expired while they were away: that one is resolved and cleared, never re-applied, because re-punishing someone for something that already ran its course is the one mistake this can't undo.
Check history
Syntax
,punishmenthistory <person>
Example
,punishmenthistory @user
Syntax
,punishmenthistory clear <person>
Example
,punishmenthistory clear @user
Syntax
,moderationhistory <staff member>
Example
,moderationhistory @moderator
Punishment history is about a member: every punishment ever recorded against them, regardless of
who issued it. Moderation history is the mirror image: every punishment a given staff member has
issued, useful for reviewing what one moderator has actually been doing. ,punishmenthistory clear
wipes a member's record; there's no equivalent for a staff member's issued-punishments list.
You can also right-click a member, then Apps → Punishment History, for the same list without
typing the command. The menu only reads — there's no way to reach the clear half from a
right-click, so a mis-click can't wipe somebody's record.
Common issues
A mute or jail command says "Invalid Mute Role" or "Invalid Jail Role". Neither role exists in
your server config yet. Run ,setup to create them, or set one directly
with ,config.
A punishment I'm sure I applied doesn't show up after a member left and rejoined. It should have re-applied automatically unless it expired while they were gone, in which case that's correct: it was already served. If it's neither of those and the role genuinely didn't come back, check the mute or jail role still exists and still sits below the bot's own highest role.
"Higher Role Hierarchy" on a command I have permission to run. The permission gate and the
hierarchy check are separate: having BAN_MEMBERS doesn't override the requirement that you
out-rank the person you're aiming it at. Check your own highest role against theirs.
A member muted before a channel existed is restricted there too. If a channel is created while they're still muted, Righteous adds the same per-channel restriction to it as to every channel that existed when the mute went on. That's deliberate: a channel that shows up mid-mute isn't a gap to mute through.
,unjail said it restored fewer roles than the member had. Read the count: it's reporting what it
could actually give back. A role that was deleted, or moved above the bot's own role, while the
member was jailed can't be restored, and a jail with no stored record (one issued before this
behaviour existed, or already cleared) restores none at all. See Why jail removes roles, and mute
doesn't.
A bulk /raid sweep punished fewer people than joined in the window. Check the summary for a
skipped count: anyone the caller doesn't outrank is deliberately left alone rather than aborting the
whole sweep.
Nothing here fixed it. The shared common issues page works the same ground from the symptom end.