RocketChat/Rocket.Chat · error · Meteor.Error

invalid-room

invalid-room

Error message

Invalid room

What it means

Thrown by saveReactWhenReadOnly when Match.test(rid, String) fails (saveReactWhenReadOnly.ts:16) — the room id argument is not a string (undefined, null, number, array, object). Meteor's Match is used here purely as an argument-type check before the DB write; nothing has been modified yet. Code 'invalid-room', details { function: 'RocketChat.saveReactWhenReadOnly' }.

Source

Thrown at apps/meteor/server/lib/rooms/settings/saveReactWhenReadOnly.ts:16

import { Message } from '@rocket.chat/core-services';
import { Rooms } from '@rocket.chat/models';
import { Match } from 'meteor/check';
import { Meteor } from 'meteor/meteor';

export const saveReactWhenReadOnly = async function (
	rid: string,
	allowReact: boolean,
	user: {
		_id: string;
		username: string;
	},
	sendMessage = true,
) {
	if (!Match.test(rid, String)) {
		throw new Meteor.Error('invalid-room', 'Invalid room', {
			function: 'RocketChat.saveReactWhenReadOnly',
		});
	}

	const result = await Rooms.setAllowReactingWhenReadOnlyById(rid, allowReact);

	if (result && sendMessage) {
		const type = allowReact ? 'room-allowed-reacting' : 'room-disallowed-reacting';

		await Message.saveSystemMessage(type, rid, '', user);
	}
};

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Pass the room _id as a string, e.g. saveReactWhenReadOnly(room._id, allowReact, user)
  2. Guard upstream: if (typeof rid !== 'string' || !rid) bail out before calling
  3. Check where rid was produced — usually a missing property or wrong destructuring one frame up
  4. Match on code 'invalid-room' only after excluding genuine not-found cases (this function cannot distinguish them)

Example fix

// before
await saveReactWhenReadOnly(room, allowReact, user);

// after
await saveReactWhenReadOnly(String(room._id), allowReact, user);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof rid !== 'string' || rid.length === 0) {
	throw new Meteor.Error('invalid-room', 'Invalid room', { function: 'RocketChat.saveReactWhenReadOnly' });
}
await saveReactWhenReadOnly(rid, allowReact, user);

Type guard

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

Prevention

When it happens

Trigger: Calling saveReactWhenReadOnly(undefined, true, user) after a failed room lookup upstream; passing a room document instead of its _id; numeric ids leaking from an external system; destructuring { rid } from an object where the key is absent.

Common situations: REST/method handlers forwarding req.body.rid that was never sent; refactor renaming roomId → rid missing one call site; mock data using array ids.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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