RocketChat/Rocket.Chat · error · Meteor.Error
error-not-allowed
error-not-allowed
Error message
Not allowed
What it means
Rooms.findOneById(rid) returned null, so getUsersOfRoom throws error-not-allowed ('Not allowed'). Despite the message, this exact throw is a not-found condition: no room document with that _id exists on this server. The misleading code comes from reusing error-not-allowed for the missing-room branch.
Source
Thrown at apps/meteor/server/meteor-methods/users/getUsersOfRoom.ts:42
}
}
Meteor.methods<ServerMethods>({
async getUsersOfRoom(rid, showAll, { limit, skip } = {}, filter) {
if (!rid) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getUsersOfRoom' });
}
check(rid, String);
const userId = Meteor.userId();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getUsersOfRoom' });
}
const room = await Rooms.findOneById(rid, { projection: { ...roomAccessAttributes, broadcast: 1 } });
if (!room) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getUsersOfRoom' });
}
if (!(await canAccessRoomAsync(room, { _id: userId }))) {
throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'getUsersOfRoom' });
}
if (room.broadcast && !(await hasPermissionAsync(userId, 'view-broadcast-member-list', rid))) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getUsersOfRoom' });
}
// TODO this is currently counting deactivated users
const total = await Subscriptions.countByRoomIdWhenUsernameExists(rid);
const { cursor } = findUsersOfRoom({
rid,
status: !showAll ? { $ne: UserStatus.OFFLINE } : undefined,
limit,
skip,View on GitHub (pinned to b2c16d5842)
Solutions
- Only pass rid values taken from a currently loaded room document
- If the room was deleted, clear the cached rid and redirect away from the members view
- Verify MONGO_URL / environment so ids resolve against the intended database
Example fix
// before
Meteor.callAsync('getUsersOfRoom', ridFromStorage, showAll);
// after
const room = Rooms.findOne({ _id: ridFromStorage });
if (!room) {
clearCachedRid();
return;
}
await Meteor.callAsync('getUsersOfRoom', room._id, showAll); Defensive patterns
Strategy: try-catch
Validate before calling
const room = Rooms.findOne({ _id: rid });
if (!room) {
clearCachedRid();
return;
}
await Meteor.callAsync('getUsersOfRoom', rid, showAll); Try / catch
try {
await Meteor.callAsync('getUsersOfRoom', rid, showAll);
} catch (err) {
if ((err as { error?: string }).error === 'error-not-allowed' && !Rooms.findOne({ _id: rid })) {
// room does not exist (message is misleading) — purge stale rid
}
} Prevention
- Only use rid values from currently loaded room documents
- Purge cached rids from localStorage/URLs when rooms are deleted
- Confirm the environment (MONGO_URL) matches where the rid was created
When it happens
Trigger: Passing a non-existent, typo'd, or already-deleted room id; a rid that belongs to a different workspace (e.g. MONGO_URL pointing at another environment's database).
Common situations: Stale rid cached in localStorage or a bookmarked URL after the room was deleted; room deleted while the tab stayed open; dev ids run against a prod database.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/58bcb26e092b7d13.
Report an issue: GitHub.