RocketChat/Rocket.Chat · warning · Meteor.Error

error-room-archived

error-room-archived

Error message

The private group, ${roomName}, is archived

What it means

Thrown by findPrivateGroupByIdOrName (groups.ts:139-141) when checkedArchived is not disabled (default true) and the resolved private group has room.archived === true. It blocks mutations against groups that have been archived, since archived groups are read-only by design. Endpoints that explicitly pass checkedArchived:false (e.g. groups.info) bypass this and instead surface archival through the returned payload.

Source

Thrown at apps/meteor/server/api/v1/groups.ts:140

	open: boolean;
	ro: boolean;
	t: string;
	name: string;
	broadcast: boolean;
}> {
	const room = await getRoomFromParams(params);

	const user = await Users.findOneById(userId, { projection: { username: 1, roles: 1, abacAttributes: 1 } });

	if (!room || !user || !(await canAccessRoomAsync(room, user))) {
		throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any group');
	}

	// discussions have their names saved on `fname` property
	const roomName = room.prid ? room.fname : room.name;

	if (checkedArchived && room.archived) {
		throw new Meteor.Error('error-room-archived', `The private group, ${roomName}, is archived`);
	}

	const sub = await Subscriptions.findOneByRoomIdAndUserId(room._id, userId, { projection: { open: 1 } });

	return {
		rid: room._id,
		open: Boolean(sub?.open),
		ro: Boolean(room.ro),
		t: room.t,
		name: roomName ?? '',
		broadcast: Boolean(room.broadcast),
	};
}

const groupResponseSchema = ajv.compile<{ group: IRoom }>({
	type: 'object',
	properties: {
		group: { $ref: '#/components/schemas/IRoom' },

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Unarchive the group first: POST groups.unarchive (executeUnarchiveRoom) or use the unarchive meteor method, then retry.
  2. If archival was unintended, have an owner unarchive via the UI/Admin panel and confirm room.archived === false before re-issuing the call.
  3. For read-only inspection, use groups.info (checkedArchived:false) which returns the group instead of throwing.
  4. Treat archived groups as terminal in your client logic and stop issuing mutations once you observe archived === true.

Example fix

// before
await POST('/api/v1/groups.rename', { roomId, name }); // group is archived -> error-room-archived

// after
await POST('/api/v1/groups.unarchive', { roomId });
await POST('/api/v1/groups.rename', { roomId, name });
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: ensure the group is not archived before mutating.
const info = await api.get('/api/v1/groups.info', { roomId }); // checkedArchived:false
if (info.group.archived) {
  throw new Error(`Group ${info.group.name} is archived; unarchive first`);
}
await api.post('/api/v1/groups.rename', { roomId, name });

Type guard

function isArchived(room) {
  return Boolean(room && room.archived === true);
}

Try / catch

try {
  await api.post('/api/v1/groups.rename', { roomId, name });
} catch (e) {
  if (isMeteorError(e) && e.reason === 'error-room-archived') {
    // optionally unarchive and retry, or surface archived state to UI
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling any groups.* mutation routed through the helper with checkedArchived defaulted (addModerator, addOwner, kick, rename, setCustomFields, setDescription, setTopic, setReadOnly, setType, setEncrypted, etc.) against a group whose archived flag is true.

Common situations: An admin archived the group but a client/bot still holds the roomId and keeps issuing edits. A workflow archives groups on a schedule and an async job races with it. CI seeds an archived fixture and forgets to unarchive it before mutating.

Related errors


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