RocketChat/Rocket.Chat · warning · Meteor.Error

error-room-archived

error-room-archived

Error message

The channel, ${room.name}, is archived

What it means

Thrown by findChannelByIdOrName when checkedArchived is true and the resolved channel has room.archived set. The channel name is interpolated into the message. This is a soft state guard, not an auth failure - the channel exists and is readable, but it has been archived.

Source

Thrown at apps/meteor/server/api/v1/channels.ts:110

		  };
	userId?: string;
	checkedArchived?: boolean;
}): Promise<IRoom> {
	const projection = { ...API.v1.defaultFieldsToExclude };

	let room;
	if ('roomId' in params) {
		room = await Rooms.findOneById(params.roomId || '', { projection });
	} else if ('roomName' in params) {
		room = await Rooms.findOneByName(params.roomName || '', { projection });
	}

	if (!room || (room.t !== 'c' && room.t !== 'l')) {
		throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any channel');
	}

	if (checkedArchived && room.archived) {
		throw new Meteor.Error('error-room-archived', `The channel, ${room.name}, is archived`);
	}
	if (userId && room.lastMessage) {
		const [lastMessage] = await normalizeMessagesForUser([room.lastMessage], userId);
		room.lastMessage = lastMessage;
	}

	return room;
}

const channelResponseSchema = ajv.compile<{ channel: IRoom }>({
	type: 'object',
	properties: {
		channel: { $ref: '#/components/schemas/IRoom' },
		success: { type: 'boolean', enum: [true] },
	},
	required: ['channel', 'success'],
	additionalProperties: false,
});

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Pass checkedArchived: false (or omit it) when the operation is valid on archived channels.
  2. Detect archived state upstream and surface a 'read-only / archived' UI instead of attempting writes.
  3. Unarchive the channel via the administration tools if the workflow requires it.

Example fix

// before
const room = await findChannelByIdOrName({
  params: { roomId },
  checkedArchived: true,
});

// after - allow archived rooms where the operation is permitted
const room = await findChannelByIdOrName({
  params: { roomId },
  checkedArchived: false,
});
if (room.archived) {
  // surface archived state to the user explicitly
}
Defensive patterns

Strategy: validation

Validate before calling

// Check archived state before calling endpoints that reject archived rooms
async function getChannelIfActive(roomId) {
  const room = await Rooms.findOneById(roomId);
  if (!room) throw new Error('Room not found');
  if (room.archived) return { archived: true, room };
  return { archived: false, room };
}

Type guard

function isArchivedRoom(room) {
  return Boolean(room) && Boolean(room.archived);
}

Try / catch

try {
  return await api.channels.info({ roomId });
} catch (e) {
  if (e.error === 'error-room-archived') {
    // surface archived state to the UI instead of failing
    return { archived: true };
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling a channels.* endpoint that passes checkedArchived: true (e.g., channels.info) against a channel whose archived flag is true.

Common situations: Operating on a channel that an admin archived mid-session; automation targeting a channel after a retention policy archived it; UI not refreshing the archived state.

Related errors


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