RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-room

error-invalid-room

Error message

Invalid room

What it means

unarchiveRoom loads the room with Rooms.findOneById(rid); a null result throws error-invalid-room. The id must identify an existing room document in the connected database before any unarchive logic runs.

Source

Thrown at apps/meteor/server/meteor-methods/rooms/unarchiveRoom.ts:29

declare module '@rocket.chat/ddp-client' {
	// eslint-disable-next-line @typescript-eslint/naming-convention
	interface ServerMethods {
		unarchiveRoom(rid: string): Promise<void>;
	}
}

export const executeUnarchiveRoom = async (userId: string, rid: string) => {
	check(rid, String);

	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' });
	}

	const room = await Rooms.findOneById(rid);

	if (!room) {
		throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'unarchiveRoom' });
	}

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

	return unarchiveRoom(rid, user);
};

Meteor.methods<ServerMethods>({
	async unarchiveRoom(rid) {
		methodDeprecationLogger.method('unarchiveRoom', '9.0.0', '/v1/channels.unarchive');
		const userId = Meteor.userId();

		if (!userId) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'unarchiveRoom' });
		}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Confirm the room exists (Rooms.findOneById, or REST rooms.info) before unarchiving
  2. If the room was deleted rather than archived, restore it from trash/backup instead of calling unarchive
  3. Check the id source and the connected database when ids systematically fail to resolve
  4. Verify the room is actually archived — unarchive is only meaningful for archived rooms

Example fix

// before
await executeUnarchiveRoom(userId, rid); // rid no longer exists

// after
const room = await Rooms.findOneById(rid, { projection: { _id: 1, archived: 1 } });
if (!room) throw new Meteor.Error('error-invalid-room', 'Invalid room');
await executeUnarchiveRoom(userId, room._id);
Defensive patterns

Strategy: validation

Validate before calling

const room = await Rooms.findOneById(rid, { projection: { _id: 1, archived: 1 } });
if (!room) {
  // rid does not resolve: refresh it or stop before calling unarchiveRoom
}

Try / catch

try {
  await Meteor.callAsync('unarchiveRoom', rid);
} catch (error) {
  if (error instanceof Meteor.Error && error.error === 'error-invalid-room') {
    // room gone: clear stale state; if it was deleted (not archived) restore via trash/backup
  }
}

Prevention

When it happens

Trigger: Calling unarchiveRoom with the id of a deleted room, an id from another workspace or environment, or a malformed/truncated id string.

Common situations: Attempting to restore a room that was permanently removed instead of archived; stale rid in admin tooling; connected to the wrong database after a migration.

Related errors


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