RocketChat/Rocket.Chat · error · Error
Invalid message id
Error message
Invalid message id
What it means
Thrown by AppMessageBridge.delete when message.id is falsy. Deletion requires the target message id; without it the bridge cannot call deleteMessage, so it rejects the call immediately. It guards against undefined/id-less message objects reaching the delete path.
Source
Thrown at apps/meteor/app/apps/server/bridges/messages.ts:62
throw new Error('Invalid editor assigned to the message for the update.');
}
// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.
const msg = await this.orch.getConverters()?.get('messages').convertAppMessage(message, true);
const editor = await Users.findOneById(message.editor.id);
if (!editor) {
throw new Error('Invalid editor assigned to the message for the update.');
}
await updateMessage(msg as IMessage, editor);
}
protected async delete(message: IAppsMessage, user: IAppsUser, appId: string): Promise<void> {
this.orch.debugLog(`The App ${appId} is deleting a message.`);
if (!message.id) {
throw new Error('Invalid message id');
}
const convertedMsg = await this.orch.getConverters()?.get('messages').convertAppMessage(message);
const convertedUser = (await Users.findOneById(user.id)) || this.orch.getConverters()?.get('users').convertToRocketChat(user);
await deleteMessage(convertedMsg as IMessage, convertedUser);
}
protected async notifyUser(user: IAppsUser, message: IAppsMessage, appId: string): Promise<void> {
this.orch.debugLog(`The App ${appId} is notifying a user.`);
const msg = await this.orch.getConverters()?.get('messages').convertAppMessage(message);
if (!msg) {
return;
}
void api.broadcast('notify.ephemeralMessage', user.id, msg.rid, {View on GitHub (pinned to f9d3ec372b)
Solutions
- Ensure message.id is set to an existing message _id before calling deleteMessage.
- Fetch the message first via the read accessor and operate on the returned object.
- Add an assertion (if (!message.id) throw) in the App with a descriptive message.
- Distinguish delete-by-id from delete-by-object at the call site.
Example fix
// before
await app.getModify().deleteMessage({ msg: 'to delete' });
// after
if (!message.id) {
throw new Error('Cannot delete a message without an id');
}
await app.getModify().deleteMessage(message); Defensive patterns
Strategy: validation
Validate before calling
function assertMessageId(message: IAppsMessage): asserts message is IAppsMessage & { id: string } {
if (!message.id) {
throw new Error('Cannot delete message: message.id is required');
}
}
assertMessageId(message);
await app.getModify().deleteMessage(message); Type guard
const hasMessageId = (m: IAppsMessage): m is IAppsMessage & { id: string } =>
typeof m.id === 'string' && m.id.length > 0; Try / catch
try {
await app.getModify().deleteMessage(message);
} catch (e) {
if ((e as Error).message === 'Invalid message id') {
// fetch the stored message and operate on its id
}
throw e;
} Prevention
- Operate on a fetched message object so id is always present.
- Add an assertion for message.id before deleteMessage.
- Do not pass freshly-constructed (pre-send) messages to delete.
When it happens
Trigger: An App calls the message modifier's delete (e.g. app.getModify().deleteMessage(message)) with a message whose id is undefined, null, or empty string.
Common situations: App builds a partial message object for deletion and forgets id; App forwards a message that lost id through serialization; App confuses a constructed message (pre-send, no id) with a stored one; refactoring dropped the id field.
Related errors
- Invalid token for livechat message
- Invalid agentId
- Invalid editor assigned to the message for the update.
- Invalid username
- Unrecognized typing scope provided
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/dbc29bb2d4ad1762.
Report an issue: GitHub.