RocketChat/Rocket.Chat · error · Error

error-max-number-simultaneous-chats-reached

error-max-number-simultaneous-chats-reached

Error message

error-max-number-simultaneous-chats-reached

What it means

Thrown at the end of validateMaxChats ('livechat.checkAgentBeforeTakeInquiry') when the agent resolves and is online but isAgentWithinChatLimits reports they are already at their simultaneous-chat limit (total and/or department scope). Same business rule as the before-join-room hook, enforced on the take-inquiry path when the waiting queue is enabled and the agent cannot skip the queue.

Solutions

  1. Close or return some of the agent's ongoing chats, then take the inquiry
  2. Raise the per-agent and per-department simultaneous chat limits in Omnichannel settings
  3. Enable 'agent skip queue' for eligible agents or route the inquiry to an agent with spare capacity

Example fix

// before: taking a queued inquiry at capacity throws
await takeInquiry(inquiry, { agentId });

// after: replicate the hook's capacity check first
const user = await Users.getAgentAndAmountOngoingChats(agentId, inquiry.department);
const { chats = 0, chatsForDepartment = 0 } = user?.queueInfo ?? {};
if (!(await isAgentWithinChatLimits({ agentId, departmentId: inquiry.department, totalChats: chats, departmentChats: chatsForDepartment }))) {
  throw new Error('Agent at max simultaneous chats');
}
await takeInquiry(inquiry, { agentId });
Defensive patterns

Strategy: validation

Validate before calling

const agentHasCapacity = async (agentId: string, departmentId?: string): Promise<boolean> => {
  const user = await Users.getAgentAndAmountOngoingChats(agentId, departmentId);
  if (!user) return false;
  const { chats = 0, chatsForDepartment = 0 } = user.queueInfo ?? {};
  return isAgentWithinChatLimits({ agentId, departmentId, totalChats: chats, departmentChats: chatsForDepartment });
};

Try / catch

try {
  await takeInquiry(inquiry, agent);
} catch (err: any) {
  if (err?.message === 'error-max-number-simultaneous-chats-reached') {
    // stop the take; close a chat or raise limits before retrying
  }
  throw err;
}

Prevention

When it happens

Trigger: Taking an inquiry from the waiting queue while ongoing chats (total or per-department) already equal the configured maximums; Livechat_waiting_queue enabled and allowAgentSkipQueue false for the agent.

Common situations: Agents at capacity clicking queued chats; limits lowered below current load; departments with tighter limits than the agent's global load.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/2e57de5e604b461a. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/ee/server/hooks/omnichannel/checkAgentBeforeTakeInquiry.ts:62

	if (await allowAgentSkipQueue(agent)) {
		cbLogger.info({ msg: 'Chat can be taken by Agent: agent can skip queue', agentId });
		return agent;
	}

	const { department: departmentId } = inquiry;
	const user = await Users.getAgentAndAmountOngoingChats(agentId, departmentId);
	if (!user) {
		cbLogger.debug({ msg: 'No valid agent found', agentId });
		throw new Error('No valid agent found');
	}

	const { queueInfo: { chats = 0, chatsForDepartment = 0 } = {} } = user;

	if (await isAgentWithinChatLimits({ agentId, departmentId, totalChats: chats, departmentChats: chatsForDepartment })) {
		return user;
	}
	throw new Error('error-max-number-simultaneous-chats-reached');
};

callbacks.add('livechat.checkAgentBeforeTakeInquiry', validateMaxChats, callbacks.priority.MEDIUM, 'livechat-before-take-inquiry');

View on GitHub (pinned to b2c16d5842)