RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-room
error-invalid-room
Error message
Invalid room
What it means
Thrown by addUsersToRoomMethod() in apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts:38 when Match.test(data.rid, String) fails — data.rid is not a string (number, undefined, null, object). This is a type-shape check only; it fires before any database lookup, so the room may or may not exist.
Source
Thrown at apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts:38
export const sanitizeUsername = (username: string) => {
const isFederatedUsername = username.includes('@') && username.includes(':');
if (isFederatedUsername) {
return username;
}
return username.replace(/(^@)|( @)/, '');
};
export const addUsersToRoomMethod = async (userId: string, data: { rid: string; users: string[] }, user?: IUser): Promise<boolean> => {
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'addUsersToRoom',
});
}
if (!Match.test(data.rid, String)) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', {
method: 'addUsersToRoom',
});
}
// Get user and room details
const room = await Rooms.findOneById(data.rid);
if (!room) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', {
method: 'addUsersToRoom',
});
}
const subscription = await Subscriptions.findOneByRoomIdAndUserId(data.rid, userId, {
projection: { _id: 1 },
});
const userInRoom = subscription != null;
if (room.t === 'd' && !isRoomNativeFederated(room)) {View on GitHub (pinned to b2c16d5842)
Solutions
- Ensure data.rid is a string before calling: if (typeof data.rid !== 'string') reject.
- Stringify ObjectIds at the boundary: String(room._id) or room._id.valueOf() when bridging from driver objects.
- Add a runtime schema check on the payload (e.g. Match.test(data, Match.ObjectIncluding({ rid: String, users: [String] }))) at your own entry points.
- For REST integrations, use POST /v1/channels.invite / POST /v1/groups.invite where room is identified by roomId and validated by the API layer.
Example fix
// before
await addUsersToRoomMethod(uid, { rid: payload.roomId?.toHexString?.() ?? payload.roomId, users });
// after
const rid = String(payload.roomId ?? '');
if (!rid) throw new Error('rid is required and must be a string');
await addUsersToRoomMethod(uid, { rid, users }); Defensive patterns
Strategy: type-guard
Validate before calling
if (!Match.test(data.rid, String)) {
throw new Error('rid must be a string');
} Type guard
const isRoomIdString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Try / catch
try {
await addUsersToRoomMethod(uid, data);
} catch (e) {
if (e instanceof Meteor.Error && e.error === 'error-invalid-room' && typeof data.rid !== 'string') {
// shape error: normalize rid to string before retry
}
} Prevention
- Validate payload shape at the boundary with Match/Object schemas.
- Stringify Mongo ObjectIds once, at the edge: String(doc._id).
- Keep TypeScript types for payloads so renames/type drift fail at compile time.
When it happens
Trigger: Calling addUsersToRoomMethod with data.rid undefined (property misspelled or missing), a numeric ID coerced by JSON inputs, an object (e.g. passing the whole room document), or null; API/migration shims that map fields incorrectly.
Common situations: Schema drift between client payloads and the method signature; refactors renaming rid to roomId without updating all callers; JSON sources where the ID arrives as a Mongo ObjectId object rather than its string form.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- error-invalid-room
- error-invalid-user
- error-invalid-user
- error-invalid-arguments
- Only channels, private groups and direct messages can be cre
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/9a1d0194ecda006a.
Report an issue: GitHub.