RocketChat/Rocket.Chat · error · Error

invalid-room

Error message

invalid-room

What it means

Thrown by VideoConferenceService.create when Rooms.findOneById(rid) returns null — the room in which the call should start does not exist. This is the first guard in create, running before the caller-user and type checks, and it applies to all call types (direct, livechat, group).

Source

Thrown at apps/meteor/server/services/video-conference/service.ts:82

const { db } = MongoInternals.defaultRemoteCollectionDriver().mongo;

const logger = new Logger('VideoConference');

export class VideoConfService extends ServiceClassInternal implements IVideoConfService {
	protected name = 'video-conference';

	// VideoConference.create: Start a video conference using the type and provider specified as arguments
	public async create(
		{ type, rid, createdBy, providerName, ...data }: VideoConferenceCreateData,
		useAppUser = true,
	): Promise<VideoConferenceInstructions> {
		return wrapExceptions(async () => {
			const room = await Rooms.findOneById<Pick<IRoom, '_id' | 't' | 'uids' | 'name' | 'fname'>>(rid, {
				projection: { t: 1, uids: 1, name: 1, fname: 1 },
			});

			if (!room) {
				throw new Error('invalid-room');
			}

			const user = await Users.findOneById<IUser>(createdBy);
			if (!user) {
				throw new Error('failed-to-load-own-data');
			}

			if (type === 'direct') {
				if (!isRoomCompatibleWithVideoConfRinging(room.t, room.uids)) {
					throw new Error('type-and-room-not-compatible');
				}

				return this.startDirect(providerName, user, room, data);
			}

			if (type === 'livechat') {
				return this.startLivechat(providerName, user, rid);
			}

View on GitHub (pinned to e4b8178b20)

Solutions

  1. Load the room before creating the call and abort with a clear UI message if missing
  2. Derive rid from a live subscription/room payload, never from a URL fragment or stale state
  3. Re-fetch room state when the room screen mounts so deleted rooms surface early
  4. Seed Rooms in test fixtures whenever seeding video conference calls

Example fix

// before
await VideoConfService.create({ type, rid, createdBy, providerName });

// after
const room = await Rooms.findOneById(rid, { projection: { t: 1, uids: 1 } });
if (!room) throw new Error('invalid-room');
await VideoConfService.create({ type, rid, createdBy, providerName });
Defensive patterns

Strategy: validation

Validate before calling

const room = await Rooms.findOneById(rid, { projection: { _id: 1 } });
if (!room) {
  throw new Meteor.Error('invalid-room', 'Room not found');
}

Try / catch

try {
  const instructions = await VideoConfService.create(payload);
} catch (err) {
  if (err instanceof Error && err.message === 'invalid-room') {
    // show 'room no longer exists' and refresh the room list
  }
  throw err;
}

Prevention

When it happens

Trigger: POST video-conference/create (or the UI call button) with a rid that was deleted, mistyped, or belongs to another deployment; calling create with undefined rid because the client never loaded the room record.

Common situations: Stale room id cached by the web client after the room was deleted; tests seeding calls without seeding rooms; multi-instance setups pointing at different databases.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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