RocketChat/Rocket.Chat · error · Meteor.Error
error-action-not-allowed
error-action-not-allowed
Error message
This is an enterprise feature
What it means
Thrown by the getReadReceipts DDP method when License.hasModule('message-read-receipt') returns false. Read receipts with user attribution are an Enterprise-only module; on a Community install (or a license without that module) the method refuses before doing any work. Code is 'error-action-not-allowed'.
Source
Thrown at apps/meteor/ee/server/meteor-methods/getReadReceipts.ts:21
import { License } from '@rocket.chat/license';
import { Messages } from '@rocket.chat/models';
import { check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
import { canAccessRoomIdAsync } from '../../../server/lib/authorization/canAccessRoom';
import { methodDeprecationLogger } from '../../../server/lib/deprecationWarningLogger';
import { ReadReceipt } from '../lib/message-read-receipt/ReadReceipt';
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
getReadReceipts(options: { messageId: IMessage['_id'] }): IReadReceiptWithUser[];
}
}
export const getReadReceiptsFunction = async function (messageId: IMessage['_id'], userId: string): Promise<IReadReceiptWithUser[]> {
if (!License.hasModule('message-read-receipt')) {
throw new Meteor.Error('error-action-not-allowed', 'This is an enterprise feature', { method: 'getReadReceipts' });
}
check(messageId, String);
const message = await Messages.findOneById(messageId, { projection: { _id: 1, rid: 1, receiptsArchived: 1 } });
if (!message) {
throw new Meteor.Error('error-invalid-message', 'Invalid message', {
method: 'getReadReceipts',
});
}
if (!(await canAccessRoomIdAsync(message.rid, userId))) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getReadReceipts' });
}
return ReadReceipt.getReceipts(message);
};
Meteor.methods<ServerMethods>({View on GitHub (pinned to f9d3ec372b)
Solutions
- Apply an Enterprise license that includes the message-read-receipt module.
- If Enterprise is not available, disable/avoid UI that calls getReadReceipts and rely on the core read-receipt indicators only.
- Confirm the license is loaded and not expired via Administration > License.
Defensive patterns
Strategy: validation
Validate before calling
import { License } from '@rocket.chat/license';
if (!License.hasModule('message-read-receipt')) {
disableReadReceiptListUI();
return;
}
const receipts = await getReadReceiptsFunction(messageId, uid); Type guard
function readReceiptsLicensed(): boolean {
return License.hasModule('message-read-receipt');
} Try / catch
try {
await Meteor.callAsync('getReadReceipts', { messageId });
} catch (e) {
if (isMeteorError(e, 'error-action-not-allowed')) {
notifyUser('Read-receipt details require an Enterprise license.');
return;
}
throw e;
} Prevention
- Gate the 'who read this' UI behind License.hasModule('message-read-receipt').
- Keep the workspace license current; monitor expiry.
- Distinguish Community vs Enterprise features in product docs.
When it happens
Trigger: Calling the getReadReceipts method (or any feature that resolves read-receipt user lists) on a workspace whose license does not include the 'message-read-receipt' module.
Common situations: Community edition deployment; Enterprise license expired or downgraded; dev/test instance without a license file loaded.
Related errors
- error-action-not-allowed
- error-action-not-allowed
- error-action-not-allowed
- error-max-guests-number-reached
- error-license-user-limit-reached
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/b94570312f16de6a.
Report an issue: GitHub.