RocketChat/Rocket.Chat · error · Error
error-not-authorized
error-not-authorized
Error message
error-not-authorized
What it means
Before closing an omnichannel room, closeLivechatRoom checks that the closing user either has a subscription in that room or holds the 'close-others-livechat-room' permission (checked asynchronously via hasPermissionAsync); otherwise it throws Error('error-not-authorized'). This guards against users closing chats they are not participating in.
Source
Thrown at apps/meteor/server/lib/omnichannel/closeLivechatRoom.ts:39
transcriptEmail?:
| {
sendToVisitor: false;
}
| {
sendToVisitor: true;
requestData: Pick<NonNullable<IOmnichannelRoom['transcriptRequest']>, 'email' | 'subject'>;
};
forceClose?: boolean;
},
): Promise<void> => {
const room = await LivechatRooms.findOneById(roomId);
if (!room) {
throw new Error('error-invalid-room');
}
const subscription = await Subscriptions.findOneByRoomIdAndUserId(roomId, user._id, { projection: { _id: 1 } });
if (!subscription && !(await hasPermissionAsync(user, 'close-others-livechat-room'))) {
throw new Error('error-not-authorized');
}
const options: CloseRoomParams['options'] = {
clientAction: true,
tags,
...(generateTranscriptPdf && { pdfTranscript: { requestedBy: user._id } }),
...(transcriptEmail && {
...(transcriptEmail.sendToVisitor
? {
emailTranscript: {
sendToVisitor: true,
requestData: {
email: transcriptEmail.requestData.email,
subject: transcriptEmail.requestData.subject,
requestedAt: new Date(),
requestedBy: user,
},
},View on GitHub (pinned to b2c16d5842)
Solutions
- Grant 'close-others-livechat-room' to the role of any user who must close other agents' chats
- Close the room as its serving agent (the user in room.servedBy), who has a subscription
- Invoke the close API with a user that actually participated in the room
- Re-audit role-permission sets after upgrades so omnichannel close permissions survive
Defensive patterns
Strategy: validation
Validate before calling
import { Subscriptions } from '@rocket.chat/models';
import { hasPermissionAsync } from '../../../authorization/server';
// Can this user close this room?
const sub = await Subscriptions.findOneByRoomIdAndUserId(roomId, user._id, { projection: { _id: 1 } });
const allowed = !!sub || (await hasPermissionAsync(user._id, 'close-others-livechat-room'));
if (!allowed) {
// close as the serving agent instead, or grant the permission first
} Try / catch
try {
await closeLivechatRoom(roomId, user, { clientAction: true });
} catch (err: any) {
if (err?.message === 'error-not-authorized') return respondForbidden('close-others-livechat-room required');
throw err;
} Prevention
- Grant 'close-others-livechat-room' to livechat-manager roles that must close other agents' chats
- Run automated close flows as the room's serving agent
- Re-audit role permission sets after major upgrades
When it happens
Trigger: A livechat manager or admin without 'close-others-livechat-room' calls closeLivechatRoom on a room they never served; a bot/integration user closes rooms it has no subscription for; the closing user id belongs to a different workspace.
Common situations: Custom roles cloned from agent that lost the permission after an upgrade reshuffled role definitions; bulk-close scripts running as a service user with no room subscriptions; permissions removed during an admin audit.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/e0c8d0abf82410bc.
Report an issue: GitHub.