RocketChat/Rocket.Chat · error · Error
Message converter not found
Error message
Message converter not found
What it means
Thrown by AppRoomBridge.getMessages when the orchestrator's converter registry does not contain a 'messages' converter. Converters are registered during Apps Engine bootstrap; their absence means the orchestrator is not initialized, was torn down, or is in a partially-initialized state. This is an infrastructure/internal-state error, not a user-input error.
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 f9d3ec372b)
Solutions
- Defer getMessages calls until after the Apps Engine is fully initialized (onPostAppInstall or runtime event handlers).
- Guard the accessor call: check that the messages accessor is available before invoking getMessages.
- In tests, provide a fully-wired orchestrator or mock the converter registry.
Example fix
// before
// called during onPreInstall
const msgs = await rooms.getMessages(roomId, opts);
// after
// called from a command/event handler after install
if (this.orch.getConverters()?.has('messages')) {
const msgs = await rooms.getMessages(roomId, opts);
} Defensive patterns
Strategy: validation
Validate before calling
// Only call getMessages after Apps Engine is fully initialized. // In your handler: const orch = this.app.getStorage() /* however you reach the orchestrator state */; // Simplest guard: defer the call to runtime command/event handlers, not lifecycle constructors.
Try / catch
try {
return await rooms.getMessages(roomId, opts, appId);
} catch (e) {
if (e instanceof Error && /Message converter not found/.test(e.message)) {
this.app.getLogger().warn('Messages converter not ready; deferring');
return [];
}
throw e;
} Prevention
- Do not call accessor methods from onPreInstall or the App constructor.
- Prefer runtime command/event handlers that run after Apps Engine bootstrap completes.
- In tests, wire a full orchestrator or mock the accessor rather than the bridge.
When it happens
Trigger: An App calls the rooms accessor's getMessages during a lifecycle hook that runs before the Apps Engine orchestrator finished wiring its converters, or after the orchestrator was disabled/uninstalled while a queued job still executed. The optional chaining getConverters()?.get('messages') returns undefined and the guard throws.
Common situations: Calling getMessages from onPreInstall / constructor; background jobs that outlive the App's disable; test harness that constructs the bridge without a full orchestrator; version mismatch where the converter key was renamed.
Related errors
- Room converter not found
- Could not get the message converter to process livechat room
- Only channels, private groups and direct messages can be cre
- Invalid user
- Room id not found
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/402e0bb9d126ad20.
Report an issue: GitHub.