RocketChat/Rocket.Chat · error · Error
error-not-allowed
error-not-allowed
Error message
error-not-allowed
What it means
Thrown by GET livechat/room.join when canAccessRoomAsync(room, user) returns false. Even with view-l-room permission, the user must pass the room-level access check; for Livechat rooms this typically requires being the assigned agent, a manager/admin, or a member of the department. The guard enforces per-room authorization after the global permission gate.
Source
Thrown at apps/meteor/server/api/v1/omnichannel/room.ts:430
throw new Error('error-invalid-user');
}
const room = await LivechatRooms.findOneById(roomId);
if (!room) {
throw new Error('error-invalid-room');
}
if (!room.open) {
throw new Error('room-closed');
}
if (!(await Omnichannel.isWithinMACLimit(room))) {
throw new Error('error-mac-limit-reached');
}
if (!(await canAccessRoomAsync(room, user))) {
throw new Error('error-not-allowed');
}
await addUserToRoom(roomId, user);
return API.v1.success();
},
},
);
API.v1.addRoute(
'livechat/room.saveInfo',
{ authRequired: true, permissionsRequired: ['view-l-room'], validateParams: isLiveChatRoomSaveInfoProps },
{
async post() {
const { roomData, guestData } = this.bodyParams;
const room = await LivechatRooms.findOneById(roomData._id);
if (!room || !isOmnichannelRoom(room)) {
throw new Error('error-invalid-room');View on GitHub (pinned to f9d3ec372b)
Solutions
- Grant the user membership in the room's department or assign them as a co-agent.
- Give the user view-livechat-manager (or equivalent) for cross-department monitoring.
- Confirm the user still holds view-l-room; permission revocation is a common cause.
- Use the proper supervisor/monitor role instead of forcing a direct join.
Example fix
// before
await GET('/api/v1/livechat/room.join', { roomId });
// after
if (!await canAccessRoomAsync(room, user)) {
await requestDepartmentMembership(room.departmentId, user._id);
return;
}
await GET('/api/v1/livechat/room.join', { roomId }); Defensive patterns
Strategy: validation
Validate before calling
const allowed = await canAccessRoomAsync(room, user);
if (!allowed) throw new ClientError('not-allowed'); Type guard
null
Try / catch
try {
await GET('/api/v1/livechat/room.join', { roomId });
} catch (e) {
if (e.message === 'error-not-allowed') { requestDepartmentAccess(room.departmentId); return; }
throw e;
} Prevention
- Pre-check canAccessRoomAsync in the UI to disable join buttons the user cannot use.
- Keep department membership and view-livechat-manager permissions aligned with the org chart.
- Use the supervisor/monitor role for read-only cross-department access instead of forcing joins.
When it happens
Trigger: GET livechat/room.join?roomId=... by an agent who is not the serving agent, not in the room's department, and lacks manager-level omnichannel permissions. Also when a non-omnichannel user with view-l-room tries to join a department-restricted room.
Common situations: Agent from department A tries to join a department B room without cross-department permission; ex-serving agent whose assignment was revoked tries to rejoin; user has view-l-room but not view-livechat-manager or livechat-monitoring.
Related errors
- error-not-authorized
- error-invalid-user
- error-not-authorized
- error-contact-not-found
- error-visitor-not-found
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/bf9c5997d81c3f4b.
Report an issue: GitHub.