RocketChat/Rocket.Chat · error · Meteor.Error
error-mac-limit-reached
error-mac-limit-reached
Error message
error-mac-limit-reached
What it means
In takeInquiry, after the agent check, the code loads the room and throws Meteor.Error('error-mac-limit-reached') when the room is missing OR Omnichannel.isWithinMACLimit(room) fails — note the compound condition: a deleted room also surfaces under this code. The MAC (Monthly Active Contacts) check enforces the workspace's enterprise omnichannel license allowance.
Solutions
- First rule out the non-license cause: confirm the room exists (db.rocketchat_room.findOne({_id: inquiry.rid}))
- Check current MAC usage in Administration > Omnichannel and compare against the license allowance
- Increase the allowance (license upgrade) or wait for the monthly reset
- Clean up orphaned inquiries whose rooms were deleted so agents don't hit the confusing error
Defensive patterns
Strategy: try-catch
Validate before calling
import { LivechatRooms } from '@rocket.chat/models';
// rule out the non-license cause first: the room may simply be gone
const room = await LivechatRooms.findOneById(inquiry.rid);
if (!room) {
return discardOrphanedInquiry(inquiry._id);
}
await Meteor.callAsync('livechat:takeInquiry', inquiryId); Try / catch
try {
await Meteor.callAsync('livechat:takeInquiry', inquiryId);
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'error-mac-limit-reached') {
// check room existence AND MAC usage — the code covers both causes
} else {
throw err;
}
} Prevention
- Purge inquiries whose rooms were deleted so agents never see this misleading code
- Monitor MAC usage vs license cap; alert admins before the limit
- When triaging, always verify the room exists before assuming a licensing problem
When it happens
Trigger: Taking an inquiry whose room no longer exists (deleted concurrently), or taking an inquiry for a contact that would exceed the workspace's monthly active contacts limit under the current license.
Common situations: License MAC cap reached mid-month (traffic spike, campaigns), expired trial with reduced allowance, or rooms removed by retention/cleanup while their inquiry was still queued — the latter masquerades as a licensing error because of the compound check.
Related errors
- error-mac-limit-reached
- error-action-not-allowed
- error-action-not-allowed
- error-agent-status-service-offline
- error-invalid-room
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/fdcfd234ea5d48e1.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/lib/omnichannel/takeInquiry.ts:48
userId,
settings.get<boolean>('Livechat_enabled_when_agent_idle'),
settings.get<boolean>('Livechat_accept_chats_with_no_agents'),
{},
);
if (!user) {
throw new Meteor.Error('error-agent-status-service-offline', 'Agent status is offline or Omnichannel service is not active', {
method: 'livechat:takeInquiry',
...(process.env.TEST_MODE && {
Livechat_enabled_when_agent_idle: settings.get<boolean>('Livechat_enabled_when_agent_idle'),
Livechat_accept_chats_with_no_agents: settings.get<boolean>('Livechat_accept_chats_with_no_agents'),
user: await Users.findOneById(userId),
}),
});
}
const room = await LivechatRooms.findOneById(inquiry.rid);
if (!room || !(await Omnichannel.isWithinMACLimit(room))) {
throw new Meteor.Error('error-mac-limit-reached');
}
const contactId = room.contactId ?? (await migrateVisitorIfMissingContact(room.v._id, room.source));
if (contactId) {
const isAgentAvailableToTakeContactInquiryResult = await isAgentAvailableToTakeContactInquiry(inquiry.v._id, room.source, contactId);
if (!isAgentAvailableToTakeContactInquiryResult.value) {
throw new Meteor.Error(isAgentAvailableToTakeContactInquiryResult.error);
}
}
const agent = {
agentId: user._id,
username: user.username,
};
await RoutingManager.takeInquiry(inquiry, agent, options ?? {}, room);
};
View on GitHub (pinned to b2c16d5842)