RocketChat/Rocket.Chat · error · Error

error-not-allowed

Error message

error-not-allowed

What it means

Thrown by findChatHistory (visitors.ts:61-63) when the room exists but canAccessRoomAsync(room, { _id: userId }) returns false — the calling user is not permitted in that livechat room (not the assigned agent, not a participant, or lacking the relevant room/omnichannel permissions). Returns HTTP 400 { success:false, error:'error-not-allowed' }.

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 f9d3ec372b)

Solutions

  1. Grant the user access to the room (assign them as agent, or grant `view-l-room`).
  2. Verify the user is the room's servedBy agent or has manager/moderator rights before calling.
  3. Use a user context that already has access (e.g. an admin/manager).

Example fix

// before
findChatHistory({ userId, roomId, visitorId, pagination }); // throws error-not-allowed

// after
if (!(await canAccessRoomAsync(room, { _id: userId }))) return forbidden();
findChatHistory({ userId, roomId, visitorId, pagination });
Defensive patterns

Strategy: validation

Validate before calling

const room = await LivechatRooms.findOneById(roomId);
if (!room) throw new Error('invalid-room');
if (!(await canAccessRoomAsync(room, { _id: userId }))) {
  throw new Error('user cannot access this room');
}
// safe to call findChatHistory

Type guard

const canAccessRoom = async (room: IOmnichannelRoom, userId: string) =>
  await canAccessRoomAsync(room, { _id: userId });

Try / catch

try { await findChatHistory({ userId, roomId, visitorId, pagination }); }
catch (e) { if (e instanceof Error && e.message === 'error-not-allowed') { /* forbidden: needs access/role */ } else throw e; }

Prevention

When it happens

Trigger: A user without access rights to the specific room calls findChatHistory (e.g. an agent not serving the room, or a user lacking view-l-room).

Common situations: Agent not assigned to the room tries to read its history; user lacks `view-l-room`; cross-department/cross-tenant access attempt.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/41f8b0e563394b40. Report an issue: GitHub.