{"record":{"id":"aa20d4d7643d3be2","repo":"RocketChat/Rocket.Chat","slug":"invalid-room-aa20d4","errorCode":null,"errorMessage":"invalid-room","messagePattern":"invalid-room","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/room.ts","lineNumber":120,"sourceCode":"\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst newRoom = await createRoom({\n\t\t\t\t\tvisitor: guest,\n\t\t\t\t\troomInfo,\n\t\t\t\t\tagent,\n\t\t\t\t\textraData: extraParams as IOmnichannelInquiryExtraData,\n\t\t\t\t});\n\n\t\t\t\treturn API.v1.success({\n\t\t\t\t\troom: newRoom,\n\t\t\t\t\tnewRoom: true,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst froom = await LivechatRooms.findOneOpenByRoomIdAndVisitorToken(rid, token, {});\n\t\t\tif (!froom) {\n\t\t\t\tthrow new Error('invalid-room');\n\t\t\t}\n\n\t\t\treturn API.v1.success({ room: froom, newRoom: false });\n\t\t},\n\t},\n);\n\n// Note: use this route if a visitor is closing a room\n// If a RC user(like eg agent) is closing a room, use the `livechat/room.closeByUser` route\nAPI.v1.addRoute(\n\t'livechat/room.close',\n\t{ validateParams: isPOSTLivechatRoomCloseParams },\n\t{\n\t\tasync post() {\n\t\t\tconst { rid, token } = this.bodyParams;\n\n\t\t\tif (!rcSettings.get('Omnichannel_allow_visitors_to_close_conversation')) {\n\t\t\t\tthrow new Error('error-not-allowed-to-close-conversation');","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/omnichannel/room.ts#L102-L138","documentation":"Thrown in the GET handler of 'livechat/room' (room.ts:118-121) when LivechatRooms.findOneOpenByRoomIdAndVisitorToken(rid, token, {}) returns null. This executes only when a rid IS provided in the query params (the !rid branch at line 80 handles room creation/lookup without rid). The query finds an OPEN room matching both the rid and the visitor token.","triggerScenarios":"Calling GET /api/v1/livechat/room?token=X&rid=Y where no open livechat room with _id=Y is associated with visitor token X. The room may be closed, may not exist, or may belong to a different visitor.","commonSituations":"The room was already closed by the visitor or an agent; rid is from a different visitor's session; rid was mistyped; the room was deleted. Note this specifically looks for OPEN rooms — a closed room will return null even if it exists.","solutions":["Check if the room exists (including closed): db.livechat_rooms.findOne({_id: rid}).","Check if it belongs to this visitor: db.livechat_rooms.findOne({_id: rid, 'v.token': token}).","Check if it's open: db.livechat_rooms.findOne({_id: rid, open: true}). If closed, a new room must be created.","If no rid is provided, the handler will create or find an open room automatically — omit rid to get a new room."],"exampleFix":"// before\nGET /api/v1/livechat/room?token=X&rid=closedRoomId\n// throws 'invalid-room' because the room is closed\n\n// after — omit rid to let the system find/create an open room\nGET /api/v1/livechat/room?token=X","handlingStrategy":"validation","validationCode":"// Check for an open room before requesting it by rid\nconst openRoom = await LivechatRooms.findOneOpenByRoomIdAndVisitorToken(rid, token);\nif (!openRoom) {\n  // omit rid to let the system find/create an open room instead\n  throw new Error(`No open room ${rid} for this visitor — create a new one instead`);\n}","typeGuard":"function isOpenRoomForVisitor(room: IOmnichannelRoom | null, token: string): room is IOmnichannelRoom {\n  return room !== null && room.open === true && room.v?.token === token;\n}","tryCatchPattern":"try {\n  await api.get(`/livechat/room?token=${token}&rid=${rid}`);\n} catch (err) {\n  if (err.message === 'invalid-room') {\n    // omit rid to find/create an open room\n    await api.get(`/livechat/room?token=${token}`);\n  }\n}","preventionTips":["When a room is closed, omit the rid parameter on the next GET /livechat/room to let the system find or create an open room.","Check room.open status client-side before requesting by rid.","Handle closed-room state transitions gracefully — do not assume a rid remains valid after closing."],"tags":["omnichannel","room","validation","closed-room","room"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}