{"record":{"id":"d0dd2a307ca2d950","repo":"RocketChat/Rocket.Chat","slug":"error-action-not-allowed-d0dd2a","errorCode":"error-action-not-allowed","errorMessage":"Message editing not allowed","messagePattern":"Message editing not allowed","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/messages/updateMessage.ts","lineNumber":57,"sourceCode":"\t\treturn;\n\t}\n\n\tif (!!message.tmid && originalMessage._id === message.tmid) {\n\t\tthrow new Meteor.Error('error-message-same-as-tmid', 'Cannot set tmid the same as the _id', {\n\t\t\tmethod: 'updateMessage',\n\t\t});\n\t}\n\n\tif (!originalMessage.tmid && !!message.tmid) {\n\t\tthrow new Meteor.Error('error-message-change-to-thread', 'Cannot update message to a thread', { method: 'updateMessage' });\n\t}\n\n\tconst _hasPermission = await hasPermissionAsync(uid, 'edit-message', message.rid);\n\tconst editAllowed = settings.get('Message_AllowEditing');\n\tconst editOwn = originalMessage.u && originalMessage.u._id === uid;\n\n\tif (!_hasPermission && (!editAllowed || !editOwn)) {\n\t\tthrow new Meteor.Error('error-action-not-allowed', 'Message editing not allowed', {\n\t\t\tmethod: 'updateMessage',\n\t\t\taction: 'Message_editing',\n\t\t});\n\t}\n\n\tconst blockEditInMinutes = settings.get('Message_AllowEditing_BlockEditInMinutes');\n\tconst bypassBlockTimeLimit = await hasPermissionAsync(uid, 'bypass-time-limit-edit-and-delete', message.rid);\n\n\tif (!bypassBlockTimeLimit && Match.test(blockEditInMinutes, Number) && blockEditInMinutes !== 0) {\n\t\tlet currentTsDiff = 0;\n\t\tlet msgTs;\n\n\t\tif (originalMessage.ts instanceof Date || Match.test(originalMessage.ts, Number)) {\n\t\t\tmsgTs = moment(originalMessage.ts);\n\t\t}\n\t\tif (msgTs) {\n\t\t\tcurrentTsDiff = moment().diff(msgTs, 'minutes');\n\t\t}","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/messages/updateMessage.ts#L39-L75","documentation":"Thrown by updateMessage when the caller may not edit the message: they lack the 'edit-message' permission in that room AND either the workspace setting Message_AllowEditing is disabled or the message belongs to another user. Holding 'edit-message' permission bypasses both the setting and the ownership check.","triggerScenarios":"A user without 'edit-message' editing their own message while Message_AllowEditing is false; any user editing someone else's message without the 'edit-message' role permission; permissions revoked between rendering the edit UI and submitting the change.","commonSituations":"Workspace security settings disabled message editing (Message_AllowEditing off); role configuration dropped edit-message; custom clients showing edit controls regardless of permission; moderation tooling editing others' messages without the role grant.","solutions":["Enable Message_AllowEditing in Administration > Message settings if users should edit their own messages","Grant the 'edit-message' permission to the caller's role (Admin > Permissions), scoped per room if needed","Client-side: hide edit affordances unless the user has edit-message OR (Message_AllowEditing AND owns the message)"],"exampleFix":"// before (edit always shown)\n{canEditMessage && <EditAction msg={msg} />}\nconst canEditMessage = true;\n\n// after\nconst canEditMessage =\n  hasPermission(uid, 'edit-message', msg.rid) ||\n  (settings.get('Message_AllowEditing') && msg.u._id === uid);","handlingStrategy":"validation","validationCode":"const uid = Meteor.userId();\nconst mayEdit =\n  !!uid &&\n  (hasPermission(uid, 'edit-message', msg.rid) ||\n    (settings.get('Message_AllowEditing') && msg.u?._id === uid));\nif (!mayEdit) {\n  hideEditUI(msg);\n}","typeGuard":"const isEditNotAllowed = (e: unknown): e is Meteor.Error =>\n  typeof e === 'object' && e !== null && (e as { error?: string }).error === 'error-action-not-allowed';","tryCatchPattern":"try {\n  await Meteor.callAsync('updateMessage', payload);\n} catch (e) {\n  if (isEditNotAllowed(e)) {\n    disableEditing(); // degrade gracefully — authorization failures must not be retried\n    return;\n  }\n  throw e;\n}","preventionTips":["Mirror the server rule in the UI: edit-message permission OR (Message_AllowEditing AND own message)","Re-evaluate permission/settings reactively so revoked rights hide the edit UI immediately","Disable the save action while an edit is in flight to avoid stale-state submits"],"tags":["rocket-chat","meteor","permissions","message-editing","authorization","settings"],"backgroundTag":"permission-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}