{"record":{"id":"9cb376b4f78e7568","repo":"RocketChat/Rocket.Chat","slug":"invalid-editor-assigned-to-the-message-for-the-upd","errorCode":null,"errorMessage":"Invalid editor assigned to the message for the update.","messagePattern":"Invalid editor assigned to the message for the update\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/messages.ts","lineNumber":44,"sourceCode":"\t\tconst definedMessage = convertedMessage as IMessage;\n\n\t\tconst sentMessage = await executeSendMessage(definedMessage.u._id, definedMessage);\n\t\treturn sentMessage._id;\n\t}\n\n\tprotected async getById(messageId: string, appId: string): Promise<IAppsMessage> {\n\t\tthis.orch.debugLog(`The App ${appId} is getting the message: \"${messageId}\"`);\n\n\t\t// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.\n\t\tconst message: IAppsMessage | undefined = await this.orch.getConverters()?.get('messages').convertById(messageId);\n\t\treturn message as IAppsMessage;\n\t}\n\n\tprotected async update(message: IAppsMessage, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is updating a message.`);\n\n\t\tif (!message.editor) {\n\t\t\tthrow new Error('Invalid editor assigned to the message for the update.');\n\t\t}\n\n\t\t// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.\n\t\tconst msg = await this.orch.getConverters()?.get('messages').convertAppMessage(message, true);\n\t\tconst editor = await Users.findOneById(message.editor.id);\n\n\t\tif (!editor) {\n\t\t\tthrow new Error('Invalid editor assigned to the message for the update.');\n\t\t}\n\n\t\tawait updateMessage(msg as IMessage, editor);\n\t}\n\n\tprotected async delete(message: IAppsMessage, user: IAppsUser, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is deleting a message.`);\n\n\t\tif (!message.id) {\n\t\t\tthrow new Error('Invalid message id');","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/app/apps/server/bridges/messages.ts#L26-L62","documentation":"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.","triggerScenarios":"An App calls the message modifier's update (e.g. app.getModify().updateMessage(message)) with a message whose editor property is undefined or null.","commonSituations":"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.","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."],"exampleFix":"// before\nawait app.getModify().updateMessage({ id: msgId, msg: 'edited' });\n\n// after\nawait app.getModify().updateMessage({\n  id: msgId,\n  msg: 'edited',\n  editor: { id: sender.id, username: sender.username },\n});","handlingStrategy":"validation","validationCode":"function assertMessageEditor(message: IAppsMessage): asserts message is IAppsMessage & { editor: { id: string } } {\n  if (!message.editor || !message.editor.id) {\n    throw new Error('Cannot update message: editor.id is required');\n  }\n}\nassertMessageEditor(message);\nawait app.getModify().updateMessage(message);","typeGuard":"const hasEditor = (m: IAppsMessage): m is IAppsMessage & { editor: { id: string } } =>\n  Boolean(m.editor && typeof m.editor.id === 'string');","tryCatchPattern":"try {\n  await app.getModify().updateMessage(message);\n} catch (e) {\n  if ((e as Error).message.includes('Invalid editor')) {\n    // attach the acting user as editor and retry\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["apps-engine","message","update","validation","editor"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}