RocketChat/Rocket.Chat · error · Error

Not_authorized

Not_authorized

Error message

Not_authorized

What it means

After the room is found, room.onHold requires the caller to either have a subscription in that room or hold the on-hold-others-livechat-room permission; otherwise Not_authorized. Entering the route already required on-hold-livechat-room, so this throw specifically means: room exists, but this user is neither in it nor allowed to act on others' rooms.

Source

Thrown at apps/meteor/ee/server/api/v1/omnichannel/rooms.ts:34

		validateParams: isLivechatRoomOnHoldProps,
		license: ['livechat-enterprise'],
	},
	{
		async post() {
			const { roomId } = this.bodyParams;

			type Room = Pick<IOmnichannelRoom, '_id' | 't' | 'open' | 'onHold' | 'u' | 'lastMessage' | 'servedBy'>;

			const room = await LivechatRooms.findOneById<Room>(roomId, {
				projection: { _id: 1, t: 1, open: 1, onHold: 1, u: 1, lastMessage: 1, servedBy: 1 },
			});
			if (!room) {
				throw new Error('error-invalid-room');
			}

			const subscription = await Subscriptions.findOneByRoomIdAndUserId(roomId, this.userId, { projection: { _id: 1 } });
			if (!subscription && !(await hasPermissionAsync(this.user, 'on-hold-others-livechat-room'))) {
				throw new Error('Not_authorized');
			}

			const onHoldBy = { _id: this.userId, username: this.user.username, name: this.user.name };
			const comment = i18n.t('Omnichannel_On_Hold_manually', {
				user: onHoldBy.name || `@${onHoldBy.username}`,
			});

			await OmnichannelEEService.placeRoomOnHold(room, comment, this.user);

			return API.v1.success();
		},
	},
);

API.v1.addRoute(
	'livechat/room.resumeOnHold',
	{
		authRequired: true,

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Grant on-hold-others-livechat-room to the caller's role (Administration -> Permissions).
  2. Or perform the call as the serving agent, i.e. a user subscribed to the room.
  3. Verify the caller's effective role/permission mapping before retrying.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await api.post('/v1/livechat/room.onHold', { roomId });
} catch (e) {
  if (e?.response?.data?.errorType === 'Not_authorized') {
    // caller is not in the room: either act as the serving agent
    // or have an admin grant 'on-hold-others-livechat-room' to the role
  } else throw e;
}

Prevention

When it happens

Trigger: A livechat manager calling POST /api/v1/livechat/room.onHold for an agent's conversation they are not a member of, while their role lacks on-hold-others-livechat-room.

Common situations: New manager roles missing the 'on-hold-others-livechat-room' permission; supervisors using service accounts with no room subscriptions; permission sets cloned from agent roles that only include on-hold-livechat-room.

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/dc3ed8e8ebf73172. Report an issue: GitHub.