RocketChat/Rocket.Chat · error · Meteor.Error

error-room-type-not-unarchivable

error-room-type-not-unarchivable

Error message

Room type: ${room.t} can not be unarchived

What it means

Thrown by /unarchiveroom when the room type's coordinator directive does not allow the ARCHIVE member action for this room. roomCoordinator.getRoomDirectives(room.t) resolves the per-type directive (channel, direct message, team, omnichannel, etc.) and allowMemberAction(room, RoomMemberActions.ARCHIVE, userId) returning false — typically for direct messages or room types that cannot be archived/unarchived — produces 'error-room-type-not-unarchivable' with the offending room.t embedded.

Source

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

		}

		const user = await Users.findOneById(userId, { projection: { username: 1, name: 1 } });
		if (!user || !isRegisterUser(user)) {
			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);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Only run /unarchive on room types that support archiving (public/private channels).
  2. Check the directive before acting: roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId).
  3. For custom room types, implement/extend the directive so allowMemberAction covers ARCHIVE when the type should support it.

Example fix

// before
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`);
}

// caller-side pre-check
const allowed = await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId);
if (!allowed) {
  // surface 'this room type cannot be unarchived' UI hint, skip the command
}
Defensive patterns

Strategy: validation

Validate before calling

import { roomCoordinator } from '@rocket.chat/core-services';
const canArchive = room &&
  (await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId));
if (!canArchive) { /* hide the unarchive action for this room type */ }

Type guard

const isUnarchivableRoomType = (t: string): boolean => t === 'c' || t === 'p'; // channels & private groups

Try / catch

try { await Meteor.callAsync('slashCommand', { command: 'unarchiveroom', ... }); } catch (e) { if (isMeteorError(e, 'error-room-type-not-unarchivable')) { /* explain: this room type can't be archived */ return; } throw e; }

Prevention

When it happens

Trigger: Running /unarchiveroom on a direct message room (t='d'), or any custom/registered room type whose directive disallows ARCHIVE, e.g. '/unarchive' inside a DM.

Common situations: Users trying to unarchive DMs or livechat rooms; custom room-type apps that did not implement allowMemberAction for ARCHIVE; team discussions of certain types.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/bbaa6cb93ac78f4a. Report an issue: GitHub.