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
- Ensure the message was sent/persisted first and pass its real id (e.g. obtained from the message reader)
- Load the message via the reader (getMessageById) and use the loaded id
- Guard the call: skip or prompt when !messageId
- 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
- Only report messages obtained from the message reader or live events (they carry ids
- Map external system ids to Rocket.Chat message ids before reporting
- Check for id vs _id naming when handling raw core objects
- Skip early with a log instead of calling the API with undefined
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)