RocketChat/Rocket.Chat · warning · Error

Room ${roomData._id} not found

Error message

Room ${roomData._id} not found

What it means

Thrown by the default branch of the livechatEvent switch for any livechat room event not matched by an explicit case. It calls convertRoom(roomData) and, if that returns null, reports the room as not found. This catches newer or unhandled livechat events whose payload is a room object.

Source

Thrown at apps/meteor/app/apps/server/bridges/listeners.ts:513

			}

			case AppInterface.IPostLivechatDepartmentRemoved: {
				const [departmentData] = args.payload;
				const department = await this.orch.getConverters().get('departments').convertDepartment(departmentData);

				if (!department) {
					throw new Error(`Department ${departmentData._id} not found`);
				}

				return this.orch.getManager().getListenerManager().executeListener(args.event, { department });
			}

			default:
				const [roomData] = args.payload;
				const room = await this.orch.getConverters().get('rooms').convertRoom(roomData);

				if (!room) {
					throw new Error(`Room ${roomData._id} not found`);
				}

				if (!isLivechatRoom(room)) {
					throw new Error(`Room ${roomData._id} is not a livechat room`);
				}

				return this.orch.getManager().getListenerManager().executeListener(args.event, room);
		}
	}

	async userEvent(args: HandleUserEvent): Promise<unknown> {
		switch (args.event) {
			case AppInterface.IPostUserLoggedIn:
			case AppInterface.IPostUserLoggedOut: {
				const [loggedInUser] = args.payload;
				const context = this.orch.getConverters().get('users').convertToApp(loggedInUser);
				return this.orch.getManager().getListenerManager().executeListener(args.event, context);
			}

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Identify which event landed in the default branch (log args.event) and confirm whether the bridge needs a dedicated case for it.
  2. Verify roomData._id maps to an existing LivechatRooms document at processing time.
  3. Ensure custom event dispatch passes a room snapshot that convertRoom can resolve.
  4. Upgrade the apps-engine bridge together with core so new events have explicit handlers.
Defensive patterns

Strategy: validation

Validate before calling

const room = await LivechatRooms.findOneById(roomData._id);
if (!room) {
  // do not dispatch a livechat event for a missing room
  return;
}
await emitEvent(args.event, { payload: [roomData] });

Type guard

const isPersistedRoom = async (data: { _id: string }): Promise<boolean> =>
  Boolean(await LivechatRooms.findOneById(data._id, { projection: { _id: 1 } }));

Try / catch

try {
  await listenerManager.executeListener(args.event, room);
} catch (e) {
  this.orch.debugLog(`Skipping ${args.event} for room ${roomData._id}: ${(e as Error).message}`);
}

Prevention

When it happens

Trigger: A livechat event reaches the default branch (no dedicated case), args.payload[0] is roomData, and convertRoom resolves falsy because the room was deleted, the payload is malformed, or roomData._id does not correspond to a persisted LivechatRooms document.

Common situations: A new livechat AppInterface event is emitted by core but no case was added to the bridge; a room is purged between the event firing and processing; a custom integration dispatches an undocumented livechat event with a synthetic/partial room payload.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/4b145f58ea8420f3. Report an issue: GitHub.