RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-room

error-invalid-room

Error message

Invalid room

What it means

getUsersOfRoom throws error-invalid-room when its first argument rid is falsy (undefined, null, empty string). This check runs before check(rid, String), so a truthy non-string value would instead fail the Match check — this error specifically means 'no room id was supplied'.

Source

Thrown at apps/meteor/server/meteor-methods/users/getUsersOfRoom.ts:30

declare module '@rocket.chat/ddp-client' {
	// eslint-disable-next-line @typescript-eslint/naming-convention
	interface ServerMethods {
		getUsersOfRoom(
			rid: IRoom['_id'],
			showAll?: boolean,
			options?: { limit?: number; skip?: number },
			filter?: string,
		): {
			total: number;
			records: IUser[];
		};
	}
}

Meteor.methods<ServerMethods>({
	async getUsersOfRoom(rid, showAll, { limit, skip } = {}, filter) {
		if (!rid) {
			throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getUsersOfRoom' });
		}

		check(rid, String);

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

		const room = await Rooms.findOneById(rid, { projection: { ...roomAccessAttributes, broadcast: 1 } });
		if (!room) {
			throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getUsersOfRoom' });
		}

		if (!(await canAccessRoomAsync(room, { _id: userId }))) {
			throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'getUsersOfRoom' });
		}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Gate the call: only invoke once rid is a non-empty string (room record loaded)
  2. Fix the source of rid — subscribe to the room or read it from the room document you already rendered
  3. Check destructuring/props for the rid field name

Example fix

// before
Meteor.callAsync('getUsersOfRoom', rid, showAll, { limit, skip }, filter);

// after
if (typeof rid !== 'string' || rid.length === 0) return;
await Meteor.callAsync('getUsersOfRoom', rid, showAll, { limit, skip }, filter);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof rid !== 'string' || rid.length === 0) {
	return { total: 0, records: [] }; // room not loaded yet
}
await Meteor.callAsync('getUsersOfRoom', rid, showAll, { limit, skip }, filter);

Type guard

const isRoomId = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;

Try / catch

try {
	await Meteor.callAsync('getUsersOfRoom', rid, showAll, options, filter);
} catch (err) {
	if ((err as { error?: string }).error === 'error-invalid-room') {
		// rid was empty/undefined — fix the data source, don't retry
	}
}

Prevention

When it happens

Trigger: Meteor.callAsync('getUsersOfRoom', rid, ...) with rid undefined or empty — typically a route param, prop, or room record that is not loaded yet when the call fires.

Common situations: Member-list component mounting before the room subscription delivered the room; deleted/renamed route param; destructuring typo ({ id } instead of { rid }).

Related errors


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