RocketChat/Rocket.Chat · error · Meteor.Error

error-not-authorized

error-not-authorized

Error message

Not authorized

What it means

After the room-type check, /archive verifies hasPermissionAsync(userId, 'archive-room', room._id). The permission is scope-aware: the user must hold archive-room either globally or on that specific room. Otherwise the command throws 'error-not-authorized' and nothing is archived.

Source

Thrown at apps/meteor/server/slashcommands/archiveroom/server.ts:56

			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-archivable', `Room type: ${room.t} can not be archived`);
		}

		if (!(await hasPermissionAsync(userId, 'archive-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('Duplicate_archived_channel_name', {
					channelName: channel,
					lng: settings.get('Language') || 'en',
				}),
			});
			return;
		}

		await archiveRoom(room._id, user);

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

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Grant the archive-room permission to the user's role (Administration > Permissions), globally or scoped to the room
  2. Ask a user who already holds the permission (typically an admin) to run /archive
  3. For room-scoped setups, add the room-scoped archive-room permission for that leader or moderator on the specific room
  4. Retry the command after the permission change propagates

Example fix

// before
runSlashCommand('/archive', { rid }); // from member without archive-room -> error-not-authorized

// after
if (!(await hasPermissionAsync(userId, 'archive-room', room._id))) {
	return notifyUser('You need the archive-room permission to archive this channel');
}
runSlashCommand('/archive', { rid });
Defensive patterns

Strategy: validation

Validate before calling

if (!(await hasPermissionAsync(userId, 'archive-room', room._id))) {
	return notifyUser('You need the archive-room permission to archive this channel');
}
runCommand('/archive', room);

Try / catch

catch (err) {
	if (err instanceof Meteor.Error && err.error === 'error-not-authorized') {
		// suggest contacting an admin or a user holding archive-room
	} else throw err;
}

Prevention

When it happens

Trigger: A regular member (non-owner, non-moderator, or a role without archive-room) running /archive in a channel; room-scoped permissions granted on other rooms but not this one; permission sets changed after a role restructuring.

Common situations: Workspaces where only admins hold archive-room; users assuming channel owners can archive by default (only if their role grants the permission); custom roles created without archive-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/2b3f5991b10591eb. Report an issue: GitHub.