RocketChat/Rocket.Chat · error · Meteor.Error
error-no-permission
error-no-permission
Error message
No permission
What it means
Thrown by 'getRoomByTypeAndName' when the authenticated user fails canAccessRoomAsync(room, user, { includeInvitations: true }) — the user is neither a member, nor invited, nor otherwise allowed to see the room. This is the authorization check that runs after the room was found and after the anonymous checks passed.
Source
Thrown at apps/meteor/server/publications/room/index.ts:88
}
const roomFind = roomCoordinator.getRoomFind(type);
const room = roomFind ? await roomFind.call(this, name) : await Rooms.findByTypeAndNameOrId(type, name);
if (!room) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', {
method: 'getRoomByTypeAndName',
});
}
if (
user &&
!(await canAccessRoomAsync(room, user, {
includeInvitations: true,
}))
) {
throw new Meteor.Error('error-no-permission', 'No permission', {
method: 'getRoomByTypeAndName',
});
}
if (settings.get('Store_Last_Message') && user && !(await hasPermissionAsync(user, 'preview-c-room'))) {
delete room.lastMessage;
}
return roomMap(room);
},
});
View on GitHub (pinned to b2c16d5842)
Solutions
- Join the room first (or ask an admin for an invitation/membership)
- Pre-check access with canAccessRoomAsync before calling the method
- Handle error-no-permission gracefully (hide content, offer a join flow)
Example fix
// before
const room = await Meteor.callAsync('getRoomByTypeAndName', 'p', name);
// after (server-side pre-check)
const room = await Rooms.findByTypeAndNameOrId('p', name);
if (!(await canAccessRoomAsync(room, user, { includeInvitations: true }))) {
throw new Meteor.Error('error-no-permission');
} Defensive patterns
Strategy: validation
Validate before calling
const room = await Rooms.findByTypeAndNameOrId(type, name);
if (!room || !(await canAccessRoomAsync(room, user, { includeInvitations: true }))) {
throw new Error('user cannot access this room');
}
Meteor.call('getRoomByTypeAndName', type, name); Type guard
async function userCanAccessRoom(user: Meteor.User, room: IRoom): Promise<boolean> {
return canAccessRoomAsync(room, user, { includeInvitations: true });
} Try / catch
try { await Meteor.callAsync('getRoomByTypeAndName', type, name); } catch (e) { if (e.error === 'error-no-permission') { /* offer join/leave flow, do not retry */ } } Prevention
- Check membership (subscriptions) before fetching private room metadata
- Refresh access state after membership or permission changes
When it happens
Trigger: A logged-in user who never joined a private channel ('p') calls getRoomByTypeAndName('p', 'private-room'); a user removed from a team channel retries the lookup; direct-message room access by a third party.
Common situations: Deep links to private rooms shared with non-members; clients that prefetch room metadata for URLs pasted in chat; permission changes (membership revoked) not yet reflected client-side.
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
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/b7c01751a36684bd.
Report an issue: GitHub.