RocketChat/Rocket.Chat · error
Not allowed
Error message
Not allowed
What it means
banUserFromRoomMethod (used by 'POST /api/v1/rooms.banUser' and the '/ban' slash command) throws a plain 'Not allowed' Error when the caller lacks the 'ban-user' permission in that room's scope. Because it is a plain Error rather than Meteor.Error, DDP clients get an opaque internal error; REST clients see the message text. It is the first of several guards in the method.
Source
Thrown at apps/meteor/server/lib/banUserFromRoom.ts:13
import { isBannedSubscription } from '@rocket.chat/core-typings';
import { Rooms, Subscriptions, Users, Roles } from '@rocket.chat/models';
import { canAccessRoomAsync } from './authorization';
import { hasPermissionAsync } from './authorization/hasPermission';
import { hasRoleAsync } from './authorization/hasRole';
import { banUserFromRoom } from './rooms/banUserFromRoom';
import { roomCoordinator } from './rooms/roomCoordinator';
import { RoomMemberActions } from '../../definition/IRoomTypeConfig';
export const banUserFromRoomMethod = async (fromId: string, data: { rid: string; username: string }): Promise<boolean> => {
if (!(await hasPermissionAsync(fromId, 'ban-user', data.rid))) {
throw new Error('Not allowed');
}
const room = await Rooms.findOneById(data.rid);
if (!room || !(await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.BAN, fromId))) {
throw new Error('Not allowed');
}
const fromUser = await Users.findOneById(fromId);
if (!fromUser) {
throw new Error('Invalid user');
}
if (!(await canAccessRoomAsync(room, fromUser))) {
throw new Error('The required "roomId" or "roomName" param provided does not match any group');
}
const bannedUser = await Users.findOneByUsernameIgnoringCase(data.username);View on GitHub (pinned to b2c16d5842)
Solutions
- Grant 'ban-user' to the acting role, globally or scoped to the room
- Check the caller's effective permissions before showing ban actions in the UI
- Retry with an admin token to confirm the permission is the cause
Defensive patterns
Strategy: validation
Validate before calling
const me = await GET '/api/v1/me';
if (!me.permissions?.includes('ban-user')) {
// hide ban actions for this user (room-scoped grants need per-room checks)
} Try / catch
try {
await POST '/api/v1/rooms.banUser' { roomId, username };
} catch (e) {
if (String(e.message).includes('Not allowed')) {
// plain Error, no code: first verify 'ban-user' permission, then room-type support
} else {
throw e;
}
} Prevention
- Check effective permissions (global and room-scoped) before showing ban actions
- Remember these are plain Errors without codes - match by message
- Test custom moderator roles against both permitted and non-permitted rooms
When it happens
Trigger: Calling rooms.banUser with a token whose user lacks 'ban-user'; a moderator role holding the permission only on certain rooms banning elsewhere; running /ban without the permission.
Common situations: Custom moderator roles missing ban-user; confusion between global and room-scoped permission grants; testing with a regular user account.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- error-action-not-allowed
- error-action-not-allowed
- The required "roomId" or "roomName" param provided does not
- User is not in this room
- User is already banned from this room
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/ed86edbab43630e8.
Report an issue: GitHub.