RocketChat/Rocket.Chat · error · Meteor.Error

error-not-authorized

error-not-authorized

Error message

Not authorized

What it means

Permission gate in /unarchiveroom: after the room type allows the ARCHIVE action, hasPermissionAsync(userId, 'unarchive-room', room._id) is evaluated (role permission, optionally scoped to the room). If the user lacks the 'unarchive-room' permission the command throws 'error-not-authorized'. Unlike the earlier user-facing branches (which send ephemeral messages), this and the room-type check are hard errors.

Source

Thrown at apps/meteor/server/slashcommands/unarchiveroom/server.ts:55

			throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'archiveRoom' });
		}

		if (!room) {
			void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
				msg: i18n.t('Channel_doesnt_exist', {
					channelName: channel,
					lng: settings.get('Language') || 'en',
				}),
			});
			return;
		}

		if (!(await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId))) {
			throw new Meteor.Error('error-room-type-not-unarchivable', `Room type: ${room.t} can not be unarchived`);
		}

		if (!(await hasPermissionAsync(userId, 'unarchive-room', room._id))) {
			throw new Meteor.Error('error-not-authorized', 'Not authorized');
		}

		if (!room.archived) {
			void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
				msg: i18n.t('Channel_already_Unarchived', {
					channelName: channel,
					lng: settings.get('Language') || 'en',
				}),
			});
			return;
		}

		await unarchiveRoom(room._id, user);

		void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
			msg: i18n.t('Channel_Unarchived', {
				channelName: channel,
				lng: settings.get('Language') || 'en',

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Grant the user (or their role) the 'unarchive-room' permission in Administration > Permissions, globally or scoped to the room/channel.
  2. Have an admin or moderator with the permission perform the unarchive.
  3. Before sending the command, check hasPermission('unarchive-room', roomId) client-side and hide/disable the action.

Example fix

// before
if (!(await hasPermissionAsync(userId, 'unarchive-room', room._id))) {
  throw new Meteor.Error('error-not-authorized', 'Not authorized');
}

// client-side pre-check to avoid the error
const canUnarchive = useHasPermission('unarchive-room', rid);
// render the /unarchive entry point only when canUnarchive is true
Defensive patterns

Strategy: validation

Validate before calling

// Client-side, before enabling the action
const canUnarchive = useHasPermission('unarchive-room', rid);
if (!canUnarchive) { /* hide/disable the unarchive control */ }

Try / catch

try { await Meteor.callAsync('slashCommand', { command: 'unarchiveroom', ... }); } catch (e) { if (isMeteorError(e, 'error-not-authorized')) { /* request unarchive-room permission or escalate to admin */ return; } throw e; }

Prevention

When it happens

Trigger: A regular member or non-admin user runs /unarchive #channel without holding a role that includes 'unarchive-room' for that room (global or room-scoped).

Common situations: Default role setups where only admin/moderator has unarchive-room; users with room-scoped roles that grant archive but not unarchive; permission removed by an admin policy change.

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