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

  1. Inspect server logs around the sendMessage pipeline and audit apps hooking message sending
  2. Verify call.rid still exists before retrying
  3. Ensure the rocket.cat system user exists — the helper falls back to it
  4. 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

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


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