RocketChat/Rocket.Chat · error · Error
failed-to-create-message
Error message
failed-to-create-message
What it means
Thrown by VideoConferenceService's announcement helper when sendMessage(user, record, room) returns a falsy value while posting the video-call message into call.rid. The room, provider app user, or rocket.cat fallback resolved, but the messaging pipeline produced no message document — an internal messaging-layer failure surfaced at the call layer. The call object itself may already exist, so retries can duplicate state.
Source
Thrown at apps/meteor/server/services/video-conference/service.ts:573
return videoConfTypes.getTypeForRoom(room, allowRinging);
}
private async createMessage(call: VideoConference, createdBy?: IUser, customBlocks?: IMessage['blocks']): Promise<IMessage['_id']> {
const record = {
t: 'videoconf',
msg: '',
groupable: false,
blocks: customBlocks || [this.buildVideoConfBlock(call._id)],
} satisfies Partial<IMessage>;
const room = await Rooms.findOneById(call.rid);
const appId = videoConfProviders.getProviderAppId(call.providerName);
const user = createdBy || (appId && (await Users.findOneByAppId(appId))) || (await Users.findOneById('rocket.cat'));
const message = await sendMessage(user, record, room);
if (!message) {
throw new Error('failed-to-create-message');
}
return message._id;
}
private async validateProvider(providerName: string): Promise<void> {
const manager = await this.getProviderManager();
const configured = await manager.isFullyConfigured(providerName).catch(() => false);
if (!configured) {
throw new Error(availabilityErrors.NOT_CONFIGURED);
}
}
private async getValidatedProvider(): Promise<string> {
if (!videoConfProviders.hasAnyProvider()) {
throw new Error(availabilityErrors.NO_APP);
}
View on GitHub (pinned to e4b8178b20)
Solutions
- Inspect server logs around the sendMessage pipeline and audit apps hooking message sending
- Verify call.rid still exists before retrying
- Ensure the rocket.cat system user exists — the helper falls back to it
- Temporarily disable message-moderation apps to confirm the cause, then allow-list call messages
Defensive patterns
Strategy: try-catch
Validate before calling
const room = await Rooms.findOneById(call.rid, { projection: { _id: 1 } });
if (!room) throw new Meteor.Error('invalid-room'); // room must exist before the announcement posts Try / catch
try {
await VideoConfService.create(payload);
} catch (err) {
if (err instanceof Error && err.message === 'failed-to-create-message') {
// call object may exist without an announcement: notify the user, check message hooks/apps, do not blind-retry
}
throw err;
} Prevention
- Audit apps hooking message sending on production
- Keep the rocket.cat system user intact
- Log announcement failures with rid and providerName for triage
When it happens
Trigger: A beforeSaveMessage/sendMessage hook or moderation app suppressing the message; the room disappearing between the initial lookup and sendMessage; a hardened install where rocket.cat was deleted and no fallback user could post.
Common situations: Message-moderation apps silently swallowing call announcements; databases where the system user was removed; races with room deletion.
Related errors
- A video conference must exist to update.
- Marketplace_Internal_Error
- Marketplace_Internal_Error
- Custom fields not enabled
- Invalid custom fields
AI-assisted analysis of RocketChat/Rocket.Chat@e4b8178b20 (2026-08-18).
Data as JSON: /api/errors/7edb4fc1ebd16f0f.
Report an issue: GitHub.