{"record":{"id":"c15a1e5bdfdb1e3e","repo":"RocketChat/Rocket.Chat","slug":"error-max-number-simultaneous-chats-reached","errorCode":"error-max-number-simultaneous-chats-reached","errorMessage":"error-max-number-simultaneous-chats-reached","messagePattern":"error-max-number-simultaneous-chats-reached","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/hooks/omnichannel/beforeJoinRoom.ts","lineNumber":30,"sourceCode":"\t\tif (!settings.get('Livechat_waiting_queue')) {\n\t\t\treturn user;\n\t\t}\n\n\t\tif (!room || !isOmnichannelRoom(room)) {\n\t\t\treturn user;\n\t\t}\n\t\tconst { departmentId } = room;\n\t\tconst userSubs = await Users.getAgentAndAmountOngoingChats(user._id, departmentId);\n\t\tif (!userSubs) {\n\t\t\treturn user;\n\t\t}\n\t\tconst { queueInfo: { chats = 0, chatsForDepartment = 0 } = {} } = userSubs;\n\n\t\tif (await isAgentWithinChatLimits({ agentId: user._id, departmentId, totalChats: chats, departmentChats: chatsForDepartment })) {\n\t\t\treturn user;\n\t\t}\n\n\t\tthrow new Error('error-max-number-simultaneous-chats-reached');\n\t},\n\tcallbacks.priority.MEDIUM,\n\t'livechat-before-join-room',\n);\n","sourceCodeStart":12,"sourceCodeEnd":35,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/hooks/omnichannel/beforeJoinRoom.ts#L12-L35","documentation":"Thrown by the 'livechat.before-join-room' hook when an agent joining (taking) a livechat room would exceed their simultaneous-chat limits. It aggregates the agent's ongoing chats (total and per department via Users.getAgentAndAmountOngoingChats) and checks them with isAgentWithinChatLimits, which honours both the global 'Livechat maximum number of simultaneous chats per agent' and the per-department limits.","triggerScenarios":"Agent closes/opens chats while at capacity and takes another room; department-specific limit lower than global; agent auto-assignment or manual 'take' racing after several simultaneous accepts.","commonSituations":"Limit settings lowered while agents were already overloaded; new department limit introduced; agents using keyboard/quick actions to take chats faster than rooms close.","solutions":["Have the agent close or return ongoing chats until below the limit, then join","Raise the agent chat limits in Administration > Omnichannel > Agents' capacity (global and/or per-department)","Route the room to another agent with spare capacity instead of forcing the join"],"exampleFix":"// before: joining and hitting error-max-number-simultaneous-chats-reached\nawait joinRoom(agentUser, rid);\n\n// after: pre-check the identical limit helper used by the hook\nconst room = await Rooms.findOneById(rid);\nconst info = await Users.getAgentAndAmountOngoingChats(agentUser._id, room.departmentId);\nconst { chats = 0, chatsForDepartment = 0 } = info?.queueInfo ?? {};\nif (!(await isAgentWithinChatLimits({\n  agentId: agentUser._id,\n  departmentId: room.departmentId,\n  totalChats: chats,\n  departmentChats: chatsForDepartment,\n}))) {\n  throw new Error('Agent at chat capacity; close a chat first');\n}\nawait joinRoom(agentUser, rid);","handlingStrategy":"validation","validationCode":"const agentCanJoin = async (agentId: string, departmentId?: string): Promise<boolean> => {\n  const info = await Users.getAgentAndAmountOngoingChats(agentId, departmentId);\n  if (!info) return false;\n  const { chats = 0, chatsForDepartment = 0 } = info.queueInfo ?? {};\n  return isAgentWithinChatLimits({ agentId, departmentId, totalChats: chats, departmentChats: chatsForDepartment });\n};","typeGuard":null,"tryCatchPattern":"try {\n  await joinRoom(agentUser, rid);\n} catch (err: any) {\n  if (err?.message === 'error-max-number-simultaneous-chats-reached') {\n    // surface 'close a chat first' or route to another agent; do not auto-retry\n  }\n  throw err;\n}","preventionTips":["Show live capacity counters in the agent desktop so takes/joins are pre-emptively blocked","Align per-department limits with global limits to avoid surprise denials","Re-check capacity immediately before automated joins, as counts change second-to-second"],"tags":["omnichannel","livechat","agent-capacity","rate-limiting"],"backgroundTag":"capacity-limit-reached","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"}