RocketChat/Rocket.Chat · error · Error

error-invalid-room

error-invalid-room

Error message

error-invalid-room

What it means

executeUnbanUserFromRoom resolves the room by id with Rooms.findOneById(rid); if no room document matches, it throws the plain Error 'error-invalid-room'. Callers (e.g. the unbanUserFromRoom method or federation events) propagate this to the client.

Source

Thrown at apps/meteor/server/lib/rooms/executeUnbanUserFromRoom.ts:11

import { Message } from '@rocket.chat/core-services';
import { isBannedSubscription, isInviteSubscription, type IUser } from '@rocket.chat/core-typings';
import { Rooms, Subscriptions, Users } from '@rocket.chat/models';

import { afterUnbanFromRoomCallback } from '../callbacks/afterUnbanFromRoomCallback';
import { notifyOnRoomChangedById, notifyOnSubscriptionChanged } from '../notifyListener';

export const executeUnbanUserFromRoom = async function (rid: string, user: IUser, byUser: IUser): Promise<void> {
	const room = await Rooms.findOneById(rid);
	if (!room) {
		throw new Error('error-invalid-room');
	}

	if (!user.username) {
		throw new Error('error-invalid-user');
	}

	const subscription = await Subscriptions.findOneByRoomIdAndUserId(rid, user._id);
	if (!subscription) {
		throw new Error('error-invalid-subscription');
	}

	// if the subscription is an invite it means we were unbanned and then invited again, then
	// the invite was accepted and we receive a leave event (meaning the user was unbanned), so
	// at this point we just need send the message to say the user was unbanned.
	if (isInviteSubscription(subscription)) {
		await Message.saveSystemMessage('user-unbanned', rid, user.username, user, {
			u: { _id: byUser._id, username: byUser.username },
		});

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the rid exists with Rooms.findOneById before calling the unban flow
  2. If the room was deleted, discard the stale ban entry or event instead of unbanning
  3. Validate federation/app event rids against current Rooms and drop orphans

Example fix

// before
await executeUnbanUserFromRoom(ridFromEvent, user, byUser);

// after
if (!(await Rooms.findOneById(rid, { projection: { _id: 1 } }))) {
  throw new Meteor.Error('error-invalid-room', `Room ${rid} not found`);
}
await executeUnbanUserFromRoom(ridFromEvent, user, byUser);
Defensive patterns

Strategy: validation

Validate before calling

const room = await Rooms.findOneById(rid, { projections: { _id: 1 } });
if (!room) {
  throw new Meteor.Error('error-invalid-room', `Room ${rid} not found`);
}
await executeUnbanUserFromRoom(rid, user, byUser);

Try / catch

try {
  await executeUnbanUserFromRoom(rid, user, byUser);
} catch (err) {
  if (err instanceof Error && err.message === 'error-invalid-room') {
    // room gone — drop the stale ban record in the UI, nothing to unban
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling executeUnbanUserFromRoom with a rid that does not exist in the Rooms collection — deleted room, typo'd/truncated id, stale rid from an old UI session or federation event referencing a room purged after the ban was created.

Common situations: Unbanning from a message action clicked in a long-open browser session after the room was deleted; federation or app events replayed with stale room ids; scripts operating on exported room ids after a partial restore.

Related errors


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