RocketChat/Rocket.Chat · error · Error
Invalid editor assigned to the message for the update.
Error message
Invalid editor assigned to the message for the update.
What it means
Thrown by AppMessageBridge.update when message.editor is falsy. The apps-engine message-update contract requires an editor (the user performing the edit); without it the bridge cannot record who modified the message, so it rejects the update before converting.
Source
Thrown at apps/meteor/app/apps/server/bridges/messages.ts:44
const definedMessage = convertedMessage as IMessage;
const sentMessage = await executeSendMessage(definedMessage.u._id, definedMessage);
return sentMessage._id;
}
protected async getById(messageId: string, appId: string): Promise<IAppsMessage> {
this.orch.debugLog(`The App ${appId} is getting the message: "${messageId}"`);
// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.
const message: IAppsMessage | undefined = await this.orch.getConverters()?.get('messages').convertById(messageId);
return message as IAppsMessage;
}
protected async update(message: IAppsMessage, appId: string): Promise<void> {
this.orch.debugLog(`The App ${appId} is updating a message.`);
if (!message.editor) {
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');View on GitHub (pinned to f9d3ec372b)
Solutions
- Set message.editor to the acting user (typically the App's user or the message sender) before calling updateMessage.
- When editing on behalf of a user, fetch that user and assign editor: { id, username }.
- Add an assertion in the App that editor is present before the update call.
- On apps-engine upgrades, re-check the IMessage.editor contract.
Example fix
// before
await app.getModify().updateMessage({ id: msgId, msg: 'edited' });
// after
await app.getModify().updateMessage({
id: msgId,
msg: 'edited',
editor: { id: sender.id, username: sender.username },
}); Defensive patterns
Strategy: validation
Validate before calling
function assertMessageEditor(message: IAppsMessage): asserts message is IAppsMessage & { editor: { id: string } } {
if (!message.editor || !message.editor.id) {
throw new Error('Cannot update message: editor.id is required');
}
}
assertMessageEditor(message);
await app.getModify().updateMessage(message); Type guard
const hasEditor = (m: IAppsMessage): m is IAppsMessage & { editor: { id: string } } =>
Boolean(m.editor && typeof m.editor.id === 'string'); Try / catch
try {
await app.getModify().updateMessage(message);
} catch (e) {
if ((e as Error).message.includes('Invalid editor')) {
// attach the acting user as editor and retry
}
throw e;
} Prevention
- Always set message.editor to the acting user before updateMessage.
- Add an assertion in the App for editor presence.
- Re-check the IMessage.editor contract on apps-engine upgrades.
When it happens
Trigger: An App calls the message modifier's update (e.g. app.getModify().updateMessage(message)) with a message whose editor property is undefined or null.
Common situations: App constructs an updated message from a fetched message but omits editor; App sets editor only on some code paths; apps-engine version where editor moved to a nested field; App forwards a message payload that lost editor through serialization.
Related errors
- Invalid token for livechat message
- Invalid message id
- Invalid username
- Unrecognized typing scope provided
- Invalid Api parameter provided, it must be a valid IApi obje
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/9cb376b4f78e7568.
Report an issue: GitHub.