RocketChat/Rocket.Chat · error · Meteor.Error
invalid-room
invalid-room
Error message
Invalid room
What it means
Thrown by saveRoomCustomFields when Match.test(rid, String) fails (saveRoomCustomFields.ts:10). First of two guards in this function: it only checks that rid is a string; the customFields payload is validated separately on the next lines. Code 'invalid-room', details { function: 'RocketChat.saveRoomCustomFields' }.
Source
Thrown at apps/meteor/server/lib/rooms/settings/saveRoomCustomFields.ts:10
import { Rooms, Subscriptions } from '@rocket.chat/models';
import { Match } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
import type { UpdateResult } from 'mongodb';
import { notifyOnSubscriptionChangedByRoomId } from '../../notifyListener';
export const saveRoomCustomFields = async function (rid: string, roomCustomFields: Record<string, any>): Promise<UpdateResult> {
if (!Match.test(rid, String)) {
throw new Meteor.Error('invalid-room', 'Invalid room', {
function: 'RocketChat.saveRoomCustomFields',
});
}
if (!Match.test(roomCustomFields, Object)) {
throw new Meteor.Error('invalid-roomCustomFields-type', 'Invalid roomCustomFields type', {
function: 'RocketChat.saveRoomCustomFields',
});
}
const ret = await Rooms.setCustomFieldsById(rid, roomCustomFields);
// Update customFields of any user's Subscription related with this rid
const { modifiedCount } = await Subscriptions.updateCustomFieldsByRoomId(rid, roomCustomFields);
if (modifiedCount) {
void notifyOnSubscriptionChangedByRoomId(rid);
}
View on GitHub (pinned to b2c16d5842)
Solutions
- Ensure the first argument is the room _id string
- Filter/validate rows in bulk scripts before invoking (skip rows without a valid rid)
- Add a boundary check in the calling method: if (typeof rid !== 'string') return badRequest
- Remember this function has a second guard ('invalid-roomCustomFields-type') — fix both argument types at once
Example fix
// before
await saveRoomCustomFields(body.rid, body.fields); // body.rid missing on some payloads
// after
if (typeof body.rid !== 'string') {
throw new Meteor.Error('invalid-room', 'Invalid room');
}
await saveRoomCustomFields(body.rid, body.fields ?? {}); 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.saveRoomCustomFields' });
}
await saveRoomCustomFields(rid, customFields); Type guard
const isRoomId = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Prevention
- Skip bulk rows lacking a valid rid before calling
- Validate both rid (string) and customFields (plain object) at once
- Log rejected rows so partial input is visible
When it happens
Trigger: saveRoomCustomFields(undefined, fields); rid from a wrong destructuring ({ rid: id }); passing a room object; numeric id from an external sync tool.
Common situations: Apps-engine or REST integrations mapping room identifiers incorrectly; bulk scripts iterating rows where some rows lack the room id column.
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/195f8a30ff013e29.
Report an issue: GitHub.