{"record":{"id":"b94570312f16de6a","repo":"RocketChat/Rocket.Chat","slug":"error-action-not-allowed-b94570","errorCode":"error-action-not-allowed","errorMessage":"This is an enterprise feature","messagePattern":"This is an enterprise feature","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/meteor-methods/getReadReceipts.ts","lineNumber":21,"sourceCode":"import { License } from '@rocket.chat/license';\nimport { Messages } from '@rocket.chat/models';\nimport { check } from 'meteor/check';\nimport { Meteor } from 'meteor/meteor';\n\nimport { canAccessRoomIdAsync } from '../../../server/lib/authorization/canAccessRoom';\nimport { methodDeprecationLogger } from '../../../server/lib/deprecationWarningLogger';\nimport { ReadReceipt } from '../lib/message-read-receipt/ReadReceipt';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tgetReadReceipts(options: { messageId: IMessage['_id'] }): IReadReceiptWithUser[];\n\t}\n}\n\nexport const getReadReceiptsFunction = async function (messageId: IMessage['_id'], userId: string): Promise<IReadReceiptWithUser[]> {\n\tif (!License.hasModule('message-read-receipt')) {\n\t\tthrow new Meteor.Error('error-action-not-allowed', 'This is an enterprise feature', { method: 'getReadReceipts' });\n\t}\n\tcheck(messageId, String);\n\n\tconst message = await Messages.findOneById(messageId, { projection: { _id: 1, rid: 1, receiptsArchived: 1 } });\n\tif (!message) {\n\t\tthrow new Meteor.Error('error-invalid-message', 'Invalid message', {\n\t\t\tmethod: 'getReadReceipts',\n\t\t});\n\t}\n\n\tif (!(await canAccessRoomIdAsync(message.rid, userId))) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getReadReceipts' });\n\t}\n\n\treturn ReadReceipt.getReceipts(message);\n};\n\nMeteor.methods<ServerMethods>({","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/meteor-methods/getReadReceipts.ts#L3-L39","documentation":"The getReadReceipts Meteor method (apps/meteor/ee/server/meteor-methods/getReadReceipts.ts:21) is an enterprise feature gated on the 'message-read-receipt' license module. When License.hasModule('message-read-receipt') is false (Community edition, or an Enterprise license without that module) the method throws Meteor.Error('error-action-not-allowed', 'This is an enterprise feature') before any other validation.","triggerScenarios":"Invoking the getReadReceipts DDP method on a workspace whose license does not include the 'message-read-receipt' module. The method is also deprecated since 9.0.0 in favor of the REST endpoint /v1/chat.getMessageReadReceipts, which is gated by the same license module.","commonSituations":"Running Community edition and clicking 'read receipts' in the message menu; trial license expired; Enterprise license renewed without the read-receipt module; apps/integrations calling the method programmatically.","solutions":["Install/activate an Enterprise license that includes the 'message-read-receipt' module","Feature-detect before invoking: guard the UI/action with License.hasModule('message-read-receipt') on the server or license state on the client","If it cannot be licensed, remove or disable the read-receipt entry point in the client so users never trigger it"],"exampleFix":"// before\nMeteor.call('getReadReceipts', { messageId }, (err, receipts) => { ... });\n\n// after\nif (!hasLicenseModule('message-read-receipt')) {\n\t// hide the action instead of calling the method\n\treturn null;\n}\nMeteor.call('getReadReceipts', { messageId }, (err, receipts) => { ... });","handlingStrategy":"validation","validationCode":"import { License } from '@rocket.chat/license';\n\nif (!License.hasModule('message-read-receipt')) {\n\t// hide the read-receipt action; calling the method will throw\n\treturn;\n}\nMeteor.call('getReadReceipts', { messageId }, cb);","typeGuard":null,"tryCatchPattern":"Meteor.call('getReadReceipts', { messageId }, (err, receipts) => {\n\tif (err) {\n\t\tif (err.error === 'error-action-not-allowed') {\n\t\t\t// enterprise feature unavailable — hide the entry point\n\t\t\treturn;\n\t\t}\n\t\tthrow err;\n\t}\n});","preventionTips":["Gate read-receipt UI on the license module so unlicensed users never trigger the call","Prefer the REST endpoint /v1/chat.getMessageReadReceipts and check its license-gated behavior in integration tests","Verify license entitlements after renewals/trials expire"],"tags":["enterprise","license","read-receipts","meteor-method","omnichannel"],"backgroundTag":"enterprise-license-required","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}