RocketChat/Rocket.Chat · error

Message converter not found

Error message

Message converter not found

What it means

AppRoomBridge.getMessages requires the orchestrator's converter registry to contain the 'messages' converter and throws when this.orch.getConverters()?.get('messages') returns undefined. On a healthy server the converters are registered while the Apps subsystem starts, so this error indicates an initialization/ordering failure rather than bad app input.

Solutions

  1. Ensure the Apps framework is enabled and the server has fully started before apps serve requests
  2. Restart the server and watch startup logs for apps orchestrator/converter errors
  3. If running a fork, verify the code that registers the 'messages' converter still executes
  4. Report upstream with server logs if it reproduces on an unmodified build
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const messages = await app.getRocketChat().getChat().getMessages(roomId, options);
} catch (err) {
  if (err instanceof Error && err.message === 'Message converter not found') {
    // server-side initialization problem — retry after startup or report
    app.getLogger().error('apps orchestrator not ready: message converter missing');
    return [];
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling the get-messages API while the Apps orchestrator is still initializing (startup race); the apps subsystem being disabled/re-enabled mid-flight; a custom or modified server build where converter registration was changed or removed.

Common situations: Deployments where app code executes before full server startup; forks of Rocket.Chat that prune apps-engine wiring; errors during orchestrator construction that silently skip converter registration (check startup logs).

Related errors


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

Appendix: source

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

		this.orch.debugLog(`The App ${appId} is getting the room's creator by name: "${roomName}"`);

		const room = await Rooms.findOneByName(roomName, {});

		if (!room?.u?._id) {
			return undefined;
		}

		return this.orch.getConverters()?.get('users').convertById(room.u._id);
	}

	protected async getMessages(roomId: string, options: GetMessagesOptions, appId: string): Promise<IMessageRaw[]> {
		this.orch.debugLog(`The App ${appId} is getting the messages of the room: "${roomId}" with options:`, options);

		const { limit, skip = 0, sort: _sort, showThreadMessages } = options;

		const messageConverter = this.orch.getConverters()?.get('messages');
		if (!messageConverter) {
			throw new Error('Message converter not found');
		}

		const threadFilterQuery = showThreadMessages ? {} : { tmid: { $exists: false } };

		// We support only one field for now
		const sort: Sort | undefined = _sort?.createdAt ? { ts: _sort.createdAt } : undefined;

		const messageQueryOptions: FindOptions<ICoreMessage> = {
			limit,
			skip,
			sort,
		};

		const query = {
			rid: roomId,
			_hidden: { $ne: true },
			t: { $exists: false },
			...threadFilterQuery,

View on GitHub (pinned to b2c16d5842)