{"record":{"id":"e98d9daa30a5a140","repo":"RocketChat/Rocket.Chat","slug":"error-mac-limit-reached-e98d9d","errorCode":"error-mac-limit-reached","errorMessage":"error-mac-limit-reached","messagePattern":"error-mac-limit-reached","errorType":"error_code","errorClass":"MeteorError","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/services/messages/hooks/BeforeSaveCheckMAC.ts","lineNumber":21,"sourceCode":"import type { IRoom, IMessage } from '@rocket.chat/core-typings';\n\nexport class BeforeSaveCheckMAC {\n\tasync isWithinLimits({ message, room }: { message: IMessage; room: IRoom }): Promise<void> {\n\t\tif (!isOmnichannelRoom(room)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (message.token) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (message.t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst canSendMessage = await Omnichannel.isWithinMACLimit(room);\n\t\tif (!canSendMessage) {\n\t\t\tthrow new MeteorError('error-mac-limit-reached');\n\t\t}\n\t}\n}\n","sourceCodeStart":3,"sourceCodeEnd":25,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/services/messages/hooks/BeforeSaveCheckMAC.ts#L3-L25","documentation":"BeforeSaveCheckMAC is a message pre-save hook enforcing the 'monthly active contacts' (MAC) enterprise license limit on omnichannel rooms. Omnichannel.isWithinMACLimit(room) returns true if the visitor already has activity recorded for the current UTC month; otherwise it checks whether the license still allows the 'monthlyActiveContacts' action. When a new contact's message would exceed the licensed MAC quota, the hook throws Meteor error-mac-limit-reached and the message is not saved. Bot messages (message.token) and system messages (message.t) are exempt.","triggerScenarios":"Sending a message in an omnichannel room whose visitor has no activity entry for the current month (moment.utc().format('YYYY-MM')) while the workspace has reached its monthlyActiveContacts license limit — the counter quota is exhausted for the month.","commonSituations":"Enterprise license MAC cap hit mid-month as new contacts write in; quota shrunk after renewal/downgrade; the omnichannel queue worker also stops on limit reached (License.onLimitReached), so new inquiries stall alongside this error.","solutions":["Raise the monthlyActiveContacts limit on the license (upgrade/renew) so new contacts are allowed again","Wait for the UTC month to roll over — MAC counting resets monthly","Verify license validity: an absent or invalidated license falls back to CE behavior with no MAC limit, so a wrongly flagged limit can indicate a license validation issue","Short-term, prioritize ongoing conversations whose contacts are already active this month"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { Omnichannel } from '@rocket.chat/core-services';\n\nconst withinLimit = await Omnichannel.isWithinMACLimit(room);\nif (!withinLimit) {\n  // do not call sendMessage for this room; surface a license-limit notice instead\n  throw new LicenseLimitError('monthlyActiveContacts');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await sendMessage(userId, { rid, msg });\n} catch (err) {\n  if (err?.error === 'error-mac-limit-reached' || err?.reason === 'error-mac-limit-reached') {\n    // NOT retryable: quota/licensing must change (limit raise, license fix, or month rollover)\n    return notifyLicenseLimitReached();\n  }\n  throw err;\n}","preventionTips":["Monitor monthlyActiveContacts usage against the licensed limit before it is reached","Treat error-mac-limit-reached as non-retryable — the quota, not the network, is the cause","Remember the check is per visitor and per UTC month; already-active contacts never re-trigger it","An invalid/absent license removes the limit (CE behavior), so also verify license validity when the error is unexpected"],"tags":["omnichannel","license","quota","monthly-active-contacts","rocket-chat"],"backgroundTag":"license-limit-reached","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}