{"record":{"id":"f6800fca2027eac4","repo":"RocketChat/Rocket.Chat","slug":"error-message-editing-blocked","errorCode":"error-message-editing-blocked","errorMessage":"Message editing is blocked","messagePattern":"Message editing is blocked","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/messages/updateMessage.ts","lineNumber":77,"sourceCode":"\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}\n\t\tif (currentTsDiff >= blockEditInMinutes) {\n\t\t\tthrow new Meteor.Error('error-message-editing-blocked', 'Message editing is blocked', {\n\t\t\t\tmethod: 'updateMessage',\n\t\t\t});\n\t\t}\n\t}\n\n\tconst user = await Users.findOneById(uid);\n\tif (!user) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'updateMessage' });\n\t}\n\tawait canSendMessageAsync(message.rid, { uid: user._id, username: user.username ?? undefined, ...user });\n\n\t// It is possible to have an empty array as the attachments property, so ensure both things exist\n\tif (originalMessage.attachments && originalMessage.attachments.length > 0 && originalMessage.attachments[0].description !== undefined) {\n\t\toriginalMessage.attachments[0].description = message.msg;\n\t\tmessage.attachments = originalMessage.attachments;\n\t\tmessage.msg = originalMessage.msg;\n\t}\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/messages/updateMessage.ts#L59-L95","documentation":"Thrown by updateMessage when editing is time-blocked: Message_AllowEditing_BlockEditInMinutes is a non-zero number, the user lacks the 'bypass-time-limit-edit-and-delete' permission, and the message's ts is at least that many minutes old. The server recomputes age from originalMessage.ts at submit time, so only edits inside the window succeed.","triggerScenarios":"Editing a message older than Message_AllowEditing_BlockEditInMinutes without the bypass permission; the window elapsing while an edit form is open, since the server re-checks on save.","commonSituations":"Compliance-driven workspaces configured with short edit windows; users leaving an editor open past the limit; testing against old seeded messages.","solutions":["Set Message_AllowEditing_BlockEditInMinutes to 0 to disable the time limit (admin setting)","Grant 'bypass-time-limit-edit-and-delete' to roles that must edit old messages (admins, moderators)","Client-side: compute the remaining window from message ts and disable the editor when it expires"],"exampleFix":"// before\nconst canEdit = hasPermission(uid, 'edit-message', rid);\n\n// after\nconst blockMins = settings.get('Message_AllowEditing_BlockEditInMinutes');\nconst bypass = hasPermission(uid, 'bypass-time-limit-edit-and-delete', rid);\nconst withinWindow = bypass || !blockMins || Date.now() - msg.ts.getTime() < blockMins * 60_000;\nconst canEdit = hasPermission(uid, 'edit-message', rid) || withinWindow;","handlingStrategy":"validation","validationCode":"const blockMins = settings.get<number>('Message_AllowEditing_BlockEditInMinutes');\nconst canStillEdit =\n  hasPermission(uid, 'bypass-time-limit-edit-and-delete', msg.rid) ||\n  !blockMins ||\n  Date.now() - new Date(msg.ts).getTime() < blockMins * 60_000;\nif (!canStillEdit) {\n  closeEditor(msg);\n}","typeGuard":"const isEditingBlocked = (e: unknown): e is Meteor.Error =>\n  typeof e === 'object' && e !== null && (e as { error?: string }).error === 'error-message-editing-blocked';","tryCatchPattern":"try {\n  await Meteor.callAsync('updateMessage', payload);\n} catch (e) {\n  if (isEditingBlocked(e)) {\n    notifyUser('The edit time window has expired');\n    closeEditor();\n    return;\n  }\n  throw e;\n}","preventionTips":["Start edit timers from the message ts and auto-close editors at the window edge","Show the remaining edit time so users save before expiry","Grant bypass-time-limit-edit-and-delete only to trusted moderator roles"],"tags":["rocket-chat","meteor","message-editing","time-limit","settings"],"backgroundTag":"edit-time-limit-exceeded","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}