RocketChat/Rocket.Chat · error · Error

invalid-list-of-rooms

Error message

invalid-list-of-rooms

What it means

Thrown by TeamService.getMatchingTeamRooms (apps/meteor/server/services/team/service.ts:639) when `rids` is truthy but not an array (e.g. a string, number, or plain object). Note the asymmetry: null/undefined rids returns [] silently — only a truthy non-array throws. The declared type is Array<string>, so this is a runtime type guard against unvalidated input from JavaScript callers or deserialized payloads.

Source

Thrown at apps/meteor/server/services/team/service.ts:639

		}

		return {
			total,
			records,
		};
	}

	async getMatchingTeamRooms(teamId: string, rids: Array<string>): Promise<Array<string>> {
		if (!teamId) {
			throw new Error('missing-teamId');
		}

		if (!rids) {
			return [];
		}

		if (!Array.isArray(rids)) {
			throw new Error('invalid-list-of-rooms');
		}

		const rooms = await Rooms.findByTeamIdAndRoomsId(teamId, rids, {
			projection: { _id: 1 },
		}).toArray();
		return rooms.map(({ _id }: { _id: string }) => _id);
	}

	async getMembersByTeamIds(teamIds: Array<string>, options: FindOptions<ITeamMember>): Promise<Array<ITeamMember>> {
		return TeamMember.findByTeamIds(teamIds, options).toArray();
	}

	async members(
		uid: string,
		teamId: string,
		canSeeAll: boolean,
		{ offset, count }: IPaginationOptions = { offset: 0, count: 50 },
		query: Filter<IUser> = {},

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Pass a genuine array of room ID strings: Team.getMatchingTeamRooms(teamId, ['room1', 'room2'])
  2. Normalize input first: const list = Array.isArray(rids) ? rids : typeof rids === 'string' ? rids.split(',').filter(Boolean) : []
  3. Pass null/undefined instead of an empty non-array if you mean 'no rooms' — null short-circuits to []

Example fix

// before
await Team.getMatchingTeamRooms(teamId, 'room1,room2'); // string → throws invalid-list-of-rooms

// after
const rids: string[] = Array.isArray(input) ? input : String(input).split(',').filter(Boolean);
await Team.getMatchingTeamRooms(teamId, rids);
Defensive patterns

Strategy: type-guard

Validate before calling

const rooms: string[] = Array.isArray(rids) ? rids.filter((r): r is string => typeof r === 'string' && r.length > 0) : [];

Type guard

const isRoomIdList = (v: unknown): v is string[] =>
	Array.isArray(v) && v.every((item) => typeof item === 'string');

Try / catch

try {
	await Team.getMatchingTeamRooms(teamId, rooms);
} catch (e) {
	if (e instanceof Error && e.message === 'invalid-list-of-rooms') {
		// payload shape wrong — normalize to string[] and retry once
	}
	throw e;
}

Prevention

When it happens

Trigger: Calling getMatchingTeamRooms(teamId, 'room1,room2') with a comma-joined string instead of ['room1','room2']; passing an object map of rooms; a JSON payload where rooms arrives as a single string because the sender serialized one element without an array. REST schemas enforce array types upstream, so this bites direct callers.

Common situations: Apps Engine integrations receiving loosely-typed payloads; REST clients sending rooms: 'abc' instead of rooms: ['abc']; code doing rooms.toString() or joining IDs for logging and accidentally forwarding the string.

Related errors


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