RocketChat/Rocket.Chat · error

Room converter not found

Error message

Room converter not found

What it means

AppRoomBridge.getRooms (rooms listing with type/discussion/team filters) requires the 'rooms' converter in the orchestrator registry and throws when this.orch.getConverters()?.get('rooms') returns undefined. Like the messages case, it is an internal invariant — converter registration happens during apps subsystem startup, so its absence signals broken initialization.

Solutions

  1. Confirm the Apps framework is enabled and startup completed (check logs for the apps orchestrator)
  2. Restart and inspect startup logs for converter registration errors
  3. On forks, verify the 'rooms' converter registration code path is intact
  4. If it persists on stock builds, gather logs and report to Rocket.Chat
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const rooms = await app.getRocketChat().getChat().getRooms(options);
} catch (err) {
  if (err instanceof Error && err.message === 'Room converter not found') {
    app.getLogger().error('apps orchestrator not ready: room converter missing');
    return [];
  }
  throw err;
}

Prevention

When it happens

Trigger: Invoking the get-rooms API before the orchestrator finished registering converters; apps framework toggled off/on around the call; a modified build where the rooms converter registration path was altered.

Common situations: Startup races in deployments that hit app endpoints immediately; custom forks trimming apps-engine integration; failed orchestrator startup logged earlier but unnoticed.

Related errors


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

Appendix: source

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

	protected async getAllRooms(filters: GetRoomsFilters = {}, options: GetRoomsOptions = {}, appId: string): Promise<Array<IRoomRaw>> {
		this.orch.debugLog(`The App ${appId} is getting all rooms with options`, options);

		const { limit = 100, skip = 0 } = options;

		const findOptions: FindOptions<ICoreRoom> = {
			sort: { ts: -1 },
			skip,
			limit: Math.min(limit, 100),
			projection: rawRoomProjection,
		};

		const { types, discussions, teams } = filters;

		const rooms: IRoomRaw[] = [];

		const roomConverter = this.orch.getConverters()?.get('rooms');
		if (!roomConverter) {
			throw new Error('Room converter not found');
		}

		for await (const room of Rooms.findAllByTypesAndDiscussionAndTeam({ types, discussions, teams }, findOptions)) {
			const converted = await roomConverter.convertRoomRaw(room);
			if (converted) {
				rooms.push(converted);
			}
		}

		return rooms;
	}

	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;
		}

View on GitHub (pinned to b2c16d5842)