RocketChat/Rocket.Chat · error

Invalid message id

Error message

Invalid message id

What it means

AppModerationBridge.report throws when the messageId passed to the moderation report API is falsy (undefined, null, ''). Reports must attach to an existing persisted message, so the bridge validates the id before calling reportMessage(messageId, description, userId || 'rocket.cat').

Solutions

  1. Ensure the message was sent/persisted first and pass its real id (e.g. obtained from the message reader)
  2. Load the message via the reader (getMessageById) and use the loaded id
  3. Guard the call: skip or prompt when !messageId
  4. Check the property name on your message object (id vs _id)

Example fix

// before
await app.getRocketChat().getModeration().reportMessage(msg?.id, description, userId); // msg?.id undefined -> throws
// after
if (!msg?.id) throw new Error('cannot report a message without an id');
await app.getRocketChat().getModeration().reportMessage(msg.id, description, userId);
Defensive patterns

Strategy: validation

Validate before calling

const reportMessage = async (messageId: unknown, description: string, userId: string) => {
  if (typeof messageId !== 'string' || messageId.trim() === '') {
    throw new Error('cannot report a message without a persisted id');
  }
  await app.getRocketChat().getModeration().reportMessage(messageId, description, userId);
};

Type guard

const hasMessageId = (m: unknown): m is { id: string } =>
  typeof m === 'object' && m !== null && typeof (m as { id?: unknown }).id === 'string' && (m as { id: string }).id.length > 0;

if (!hasMessageId(msg)) return;

Try / catch

try {
  await app.getRocketChat().getModeration().reportMessage(messageId, description, userId);
} catch (err) {
  if (err instanceof Error && err.message === 'Invalid message id') {
    app.getLogger().warn('report skipped: no message id');
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: An app calls the moderation report API with a message object that was built locally and never persisted (no id), with a destructured/misspelled field that yields undefined, or with an empty string from untrusted input.

Common situations: Reporting messages received from webhooks or external systems where the id field is named differently; passing message.id of a draft/unsent message; id lost through JSON round-trips.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/app/apps/server/bridges/moderation.ts:18

import type { IAppServerOrchestrator } from '@rocket.chat/apps';
import { ModerationBridge } from '@rocket.chat/apps/dist/server/bridges/ModerationBridge';
import type { IMessage } from '@rocket.chat/apps-engine/definition/messages';
import type { IUser } from '@rocket.chat/apps-engine/definition/users';
import { ModerationReports } from '@rocket.chat/models';

import { reportMessage } from '../../../../server/lib/moderation/reportMessage';

export class AppModerationBridge extends ModerationBridge {
	constructor(private readonly orch: IAppServerOrchestrator) {
		super();
	}

	protected async report(messageId: IMessage['id'], description: string, userId: string, appId: string): Promise<void> {
		this.orch.debugLog(`The App ${appId} is creating a new report.`);

		if (!messageId) {
			throw new Error('Invalid message id');
		}

		if (!description) {
			throw new Error('Invalid description');
		}

		await reportMessage(messageId, description, userId || 'rocket.cat');
	}

	protected async dismissReportsByMessageId(messageId: IMessage['id'], reason: string, action: string, appId: string): Promise<void> {
		this.orch.debugLog(`The App ${appId} is dismissing reports by message id.`);

		if (!messageId) {
			throw new Error('Invalid message id');
		}

		await ModerationReports.hideMessageReportsByMessageId(messageId, appId, reason, action);
	}

View on GitHub (pinned to b2c16d5842)