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
- Grant on-hold-others-livechat-room to the caller's role (Administration -> Permissions).
- Or perform the call as the serving agent, i.e. a user subscribed to the room.
- 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
- Audit role permissions before building on-hold automations: route permission is not enough.
- Prefer executing on-hold as a user subscribed to the room.
- Distinguish 403 Not_authorized from invalid-room in error reporting.
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.