RocketChat/Rocket.Chat · error · Error
error-not-allowed
Error message
error-not-allowed
What it means
After the room resolves, findChatHistory (GET /api/v1/livechat/visitors.chathistory/:roomId/:visitorId) checks canAccessRoomAsync(room, { _id: userId }); when the requesting user cannot access that omnichannel room it throws 'error-not-allowed'. Access typically requires being the serving agent, a room member, or holding broad omnichannel read permissions.
Solutions
- Ensure the caller is the room's serving agent or a member; otherwise assign the room first.
- Grant view-l-room to the role, or use livechat-manager / omnichannel monitor roles for supervisors who must read all chats.
- Scope your UI so agents only request histories of rooms they can access.
Defensive patterns
Strategy: validation
Validate before calling
// Only fetch history for rooms the caller can access
const accessible = await canAccessRoom(roomId, userId); // rooms.info membership check or room list lookup
if (!accessible) throw new ForbiddenError('caller cannot access this room');
return getChatHistory({ userId, roomId, visitorId, pagination }); Try / catch
try { return await getChatHistory({ userId, roomId, visitorId, pagination }); } catch (e) { if (e.message === 'error-not-allowed') return forbiddenPage(); throw e; } Prevention
- Scope history UI to rooms the agent serves or monitors.
- Grant view-l-room or livechat-manager/monitor to supervisors who need cross-room reads.
- Don't run chat-history scripts with service credentials that have no room membership.
When it happens
Trigger: An agent without membership in the room (not servedBy, not a member) requests another agent's chat history; a plain authenticated user with no view-l-room/omnichannel-manager permissions calls the endpoint.
Common situations: Agents opening arbitrary visitor histories from a shared list without being assigned; custom roles missing omnichannel permissions; supervisors without the livechat-manager/monitor role trying to read all conversations.
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/41f8b0e563394b40.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/api/v1/omnichannel/lib/visitors.ts:62
}
export async function findChatHistory({
userId,
roomId,
visitorId,
pagination: { offset, count, sort },
}: {
userId: IUser['_id'];
roomId: IRoom['_id'];
visitorId: IVisitor['_id'];
pagination: { offset: number; count: number; sort: FindOptions<IOmnichannelRoom>['sort'] };
}) {
const room = await LivechatRooms.findOneById(roomId);
if (!room) {
throw new Error('invalid-room');
}
if (!(await canAccessRoomAsync(room, { _id: userId }))) {
throw new Error('error-not-allowed');
}
const extraQuery = await callbacks.run('livechat.applyRoomRestrictions', {}, { userId });
const { cursor, totalCount } = LivechatRooms.findPaginatedByVisitorId(
visitorId,
{
sort: sort || { ts: -1 },
skip: offset,
limit: count,
},
extraQuery,
);
const [history, total] = await Promise.all([cursor.toArray(), totalCount]);
return {
history,
count: history.length,View on GitHub (pinned to b2c16d5842)