RocketChat/Rocket.Chat · error

Room id not found

Error message

Room id not found

What it means

AppRoomBridge.update performs Rooms.updateOne({ _id: room.id }, { $set: rm }) and throws 'Room id not found' when matchedCount is 0 — i.e. no room document exists with that id (deleted, never existed, or from a different database). The apps-engine room object's id is stale at update time.

Solutions

  1. Verify existence first with the room reader (read.getRoomById) before updating
  2. On failure, re-fetch fresh state and retry once; if still missing, discard the cached id
  3. Avoid persisting room ids beyond their usefulness; resolve ids at execution time
  4. Validate user-supplied room ids against the reader before attempting updates

Example fix

// before
await app.getRocketChat().getChat().updateRoom(cachedRoom, members); // room deleted -> throws
// after
const fresh = await this.read.getRoomById(cachedRoom.id);
if (!fresh) { app.getLogger().warn('room no longer exists, dropping state'); return; }
await app.getRocketChat().getChat().updateRoom(fresh, members);
Defensive patterns

Strategy: validation

Validate before calling

const fresh = await this.read.getRoomById(room.id);
if (!fresh) {
  app.getLogger().warn(`room ${room.id} no longer exists; dropping cached state`);
  return;
}
await app.getRocketChat().getChat().updateRoom(fresh, members);

Try / catch

try {
  await app.getRocketChat().getChat().updateRoom(room, members);
} catch (err) {
  if (err instanceof Error && err.message === 'Room id not found') {
    const fresh = await this.read.getRoomById(room.id);
    if (!fresh) return; // room deleted — drop state
    return app.getRocketChat().getChat().updateRoom(fresh, members); // retry once with fresh data
  }
  throw err;
}

Prevention

When it happens

Trigger: The room was deleted between when the app fetched it and when it called update; room.id came from persisted/cached state after a DB restore or migration; a hand-typed or user-supplied id with a typo.

Common situations: Long-running apps caching room ids; rooms removed by retention/cleanup policies; workspaces re-imported without old room ids; race between moderators deleting rooms and app background jobs.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/app/apps/server/bridges/rooms.ts:239

	protected async getDirectByUsernames(usernames: Array<string>, appId: string): Promise<IRoom | undefined> {
		this.orch.debugLog(`The App ${appId} is getting direct room by usernames: "${usernames}"`);
		const room = await Rooms.findDirectRoomContainingAllUsernames(usernames, {});
		if (!room) {
			return undefined;
		}
		return this.orch.getConverters()?.get('rooms').convertRoom(room);
	}

	protected async update(room: IRoom, members: Array<string> = [], appId: string): Promise<void> {
		this.orch.debugLog(`The App ${appId} is updating a room.`);

		const rm = await this.orch.getConverters()?.get('rooms').convertAppRoom(room, true);

		const updateResult = await Rooms.updateOne({ _id: room.id }, { $set: rm });

		if (!updateResult.matchedCount) {
			throw new Error('Room id not found');
		}

		for (const username of members) {
			const member = await Users.findOneByUsername(username, {});

			if (!member) {
				continue;
			}

			await addUserToRoom(room.id, member);
		}
	}

	protected async delete(roomId: string, appId: string): Promise<void> {
		this.orch.debugLog(`The App ${appId} is deleting a room.`);
		await deleteRoom(roomId);
	}

View on GitHub (pinned to b2c16d5842)