RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-room
error-invalid-room
Error message
Invalid room
What it means
Thrown by addRoomOwner() in apps/meteor/server/meteor-methods/rooms/addRoomOwner.ts:30 when Rooms.findOneById(rid) returns null — no room document matches the supplied room ID. The lookup only projects t/federated/federation, so the ID must exist as a room _id. It fires before any permission or federation checks, making 'room does not exist' the first gate of the operation.
Source
Thrown at apps/meteor/server/meteor-methods/rooms/addRoomOwner.ts:30
import { notifyOnSubscriptionChangedById } from '../../lib/notifyListener';
import { syncRoomRolePriorityForUserAndRoom } from '../../lib/roles/syncRoomRolePriority';
import { isFederationEnabled, FederationMatrixInvalidConfigurationError } from '../../services/federation/utils';
import { settings } from '../../settings';
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
addRoomOwner(rid: IRoom['_id'], userId: IUser['_id']): boolean;
}
}
export const addRoomOwner = async (fromUserId: IUser['_id'], rid: IRoom['_id'], userId: IUser['_id']): Promise<boolean> => {
check(rid, String);
check(userId, String);
const room = await Rooms.findOneById(rid, { projection: { t: 1, federated: 1, federation: 1 } });
if (!room) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', {
method: 'addRoomOwner',
});
}
const isFederated = isRoomFederated(room);
if (!(await hasPermissionAsync(fromUserId, 'set-owner', rid)) && !isFederated) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', {
method: 'addRoomOwner',
});
}
if (isFederated && !isFederationEnabled()) {
throw new FederationMatrixInvalidConfigurationError('unable to change room owners');
}
const user = await Users.findOneById(userId);
View on GitHub (pinned to b2c16d5842)
Solutions
- Verify the rid exists: on the server await Rooms.findOneById(rid, { projection: { _id: 1 } }); on the client call the rooms API to confirm the room is still available.
- Re-fetch the rid at the point of use (e.g. from the current subscription/room record) instead of caching it long-term.
- Confirm you are on the correct workspace/environment for that room ID.
- Prefer the REST endpoints POST /v1/channels.addOwner / POST /v1/groups.addOwner, which return structured 400 invalid-room responses.
Example fix
// before
await addRoomOwner(uid, '665f0c1e2f7ba1a4b9a2c111', userId);
// after
const room = await Rooms.findOneById(rid, { projection: { _id: 1 } });
if (!room) throw new Error(`room ${rid} not found; refresh rid`);
await addRoomOwner(uid, room._id, userId); Defensive patterns
Strategy: validation
Validate before calling
const room = await Rooms.findOneById(rid, { projection: { _id: 1 } });
if (!room) throw new Error(`room ${rid} not found`); Type guard
const isRoomId = (v: unknown): v is string => typeof v === 'string' && /^[A-Za-z0-9]{17}$/.test(v); Try / catch
try {
await addRoomOwner(uid, rid, userId);
} catch (e) {
if (e instanceof Meteor.Error && e.error === 'error-invalid-room') {
// refresh rid from the current room/subscription context
}
} Prevention
- Always resolve rid from a live room/subscription document rather than persisted strings.
- Validate IDs at the API boundary (type + format) before they reach method calls.
- Prefer REST addOwner endpoints for clearer error bodies.
When it happens
Trigger: Calling addRoomOwner / the 'addRoomOwner' Meteor method / flows that reuse it with a rid that is not a room _id (e.g. a subscription _id, a message rid typo, an ID from another workspace, or a room that was deleted). Also triggered by stale rid values cached in client code after the room was removed.
Common situations: Copy-pasting the wrong ObjectId from the database; referencing a deleted channel; environment mismatch (dev rid used against prod); federation scenarios where the remote room ID format differs; client code holding a rid across room deletion.
Related errors
- error-invalid-user
- error-invalid-user
- error-invalid-room
- Only channels, private groups and direct messages can be cre
- Invalid user
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/4aca06553d71a6e2.
Report an issue: GitHub.