{"record":{"id":"2afa2bd3b5e60618","repo":"RocketChat/Rocket.Chat","slug":"error-room-not-served","errorCode":null,"errorMessage":"error-room-not-served","messagePattern":"error-room-not-served","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/local-services/omnichannel.internalService.ts","lineNumber":101,"sourceCode":"\t\tthis.logger.debug({ msg: 'Attempting to resume room on hold', roomId: room._id, userId: resumeBy?._id });\n\n\t\tif (!room || !isOmnichannelRoom(room)) {\n\t\t\tthrow new Error('error-invalid-room');\n\t\t}\n\n\t\tif (!room.open) {\n\t\t\tthrow new Error('This_conversation_is_already_closed');\n\t\t}\n\n\t\tif (!room.onHold) {\n\t\t\tthrow new Error('error-room-not-on-hold');\n\t\t}\n\n\t\tconst { _id: roomId, servedBy } = room;\n\n\t\tif (!servedBy) {\n\t\t\tthis.logger.error({ msg: 'No serving agent found for room', roomId });\n\t\t\tthrow new Error('error-room-not-served');\n\t\t}\n\n\t\tconst inquiry = await LivechatInquiry.findOneByRoomId(roomId, {});\n\t\tif (!inquiry) {\n\t\t\tthis.logger.error({ msg: 'No inquiry found for room', roomId });\n\t\t\tthrow new Error('error-invalid-inquiry');\n\t\t}\n\n\t\tawait this.attemptToAssignRoomToServingAgentElseQueueIt({\n\t\t\troom,\n\t\t\tinquiry,\n\t\t\tservingAgent: servedBy,\n\t\t\tclientAction,\n\t\t});\n\n\t\tconst [roomResult, subsResult] = await Promise.all([\n\t\t\tLivechatRooms.unsetOnHoldByRoomId(roomId),\n\t\t\tSubscriptions.unsetOnHoldByRoomId(roomId),","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/local-services/omnichannel.internalService.ts#L83-L119","documentation":"Thrown by resumeRoomOnHold when `servedBy` is falsy on the room. The service cannot resume a held chat that has no serving agent to hand it back to; it logs 'No serving agent found for room' at error level before throwing.","triggerScenarios":"Resuming a held room whose servedBy was cleared — e.g. the agent was removed during the hold, the assignment was invalidated, or the room was queued while held.","commonSituations":"Agent was deleted/deactivated while the chat was held; an admin manually cleared servedBy; data inconsistency where onHold is true but servedBy is missing.","solutions":["Before resume, verify room.servedBy; if missing, route through reassignment/queue rather than resume.","Investigate data integrity if onHold rooms routinely lack servedBy (backfill servedBy or unset onHold).","Surface a clear 'no agent assigned' message in the UI instead of the generic error."],"exampleFix":"// before\nawait omnichannelService.resumeRoomOnHold(room, comment, user);\n\n// after\nif (!room.servedBy) {\n  await reassignOrQueueRoom(room);\n  return;\n}\nawait omnichannelService.resumeRoomOnHold(room, comment, user);","handlingStrategy":"validation","validationCode":"if (!room.servedBy) {\n  await reassignOrQueueRoom(room);\n  return;\n}\nawait omnichannelService.resumeRoomOnHold(room, comment, user);","typeGuard":"function hasServerAgent(room: unknown): room is { servedBy: { agentId: string } } {\n  return !!room && !!(room as any).servedBy;\n}","tryCatchPattern":"try {\n  await omnichannelService.resumeRoomOnHold(room, comment, user);\n} catch (e) {\n  if (e instanceof Error && e.message === 'error-room-not-served') {\n    await reassignOrQueueRoom(room);\n    return;\n  }\n  throw e;\n}","preventionTips":["Verify servedBy before offering Resume.","Investigate data integrity when held rooms lack servedBy.","Surface 'no agent assigned' clearly to the operator."],"tags":["omnichannel","livechat","agent-assignment","data-integrity"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}