{"record":{"id":"e86bd0aaed73183a","repo":"RocketChat/Rocket.Chat","slug":"error-this-is-not-a-livechat-room","errorCode":"error-this-is-not-a-livechat-room","errorMessage":"error-this-is-not-a-livechat-room","messagePattern":"error-this-is-not-a-livechat-room","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/omnichannel/rooms.ts","lineNumber":279,"sourceCode":"\t\tlivechatLogger.error({ err });\n\t\tthrow new Meteor.Error('error-returning-inquiry');\n\t}\n\n\tcallbacks.runAsync('livechat:afterReturnRoomAsInquiry', { room });\n\n\treturn true;\n}\n\nexport async function removeOmnichannelRoom(rid: string) {\n\tlivechatLogger.debug({ msg: 'Deleting room', roomId: rid });\n\tcheck(rid, String);\n\tconst room = await LivechatRooms.findOneById(rid);\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room');\n\t}\n\n\tif (!isOmnichannelRoom(room)) {\n\t\tthrow new Meteor.Error('error-this-is-not-a-livechat-room');\n\t}\n\n\tif (room.open) {\n\t\tthrow new Meteor.Error('error-room-is-not-closed');\n\t}\n\n\tconst inquiry = await LivechatInquiry.findOneByRoomId(rid);\n\n\tconst result = await Promise.allSettled([\n\t\tMessages.removeByRoomId(rid),\n\t\tReadReceipts.removeByRoomId(rid),\n\t\tSubscriptions.removeByRoomId(rid, {\n\t\t\tasync onTrash(doc) {\n\t\t\t\tvoid notifyOnSubscriptionChanged(doc, 'removed');\n\t\t\t},\n\t\t}),\n\t\tLivechatInquiry.removeByRoomId(rid),\n\t\tLivechatRooms.removeById(rid),","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/omnichannel/rooms.ts#L261-L297","documentation":"After the room is found, removeOmnichannelRoom validates it with isOmnichannelRoom(room); non-omnichannel rooms (channels, teams, direct messages) are rejected with Meteor.Error('error-this-is-not-a-livechat-room') before deletion.","triggerScenarios":"Passing the rid of a regular channel, team, or DM into the omnichannel room removal flow.","commonSituations":"Integrations reuse one generic 'delete room' routine for all room types; a UI list mixes omnichannel conversations with normal rooms and passes the wrong id.","solutions":["Route deletion by room type: use the omnichannel removal flow only for livechat rooms (room.t === 'l').","Check room.t before calling removeOmnichannelRoom.","Use the appropriate deletion endpoint for non-omnichannel rooms."],"exampleFix":"// before\nawait removeOmnichannelRoom(rid); // rid belongs to a channel -> error-this-is-not-a-livechat-room\n\n// after\nconst room = await LivechatRooms.findOneById(rid);\nif (room?.t !== 'l') {\n\tthrow new Error('not an omnichannel room');\n}\nawait removeOmnichannelRoom(rid);","handlingStrategy":"type-guard","validationCode":"const room = await LivechatRooms.findOneById(rid, { projection: { _id: 1, t: 1 } });\nif (!room || room.t !== 'l') {\n\tthrow new Error('not an omnichannel room');\n}\nawait removeOmnichannelRoom(rid);","typeGuard":"const isOmnichannelRoomById = async (rid: string): Promise<boolean> => {\n\tconst room = await LivechatRooms.findOneById(rid, { projection: { t: 1 } });\n\treturn room?.t === 'l';\n};","tryCatchPattern":"try {\n\tawait removeOmnichannelRoom(rid);\n} catch (err) {\n\tif (err instanceof Meteor.Error && err.error === 'error-this-is-not-a-livechat-room') {\n\t\t// route this rid to the non-omnichannel deletion path instead\n\t\treturn;\n\t}\n\tthrow err;\n}","preventionTips":["Branch deletion logic on room.t before choosing an API.","Keep omnichannel conversations and normal rooms in separate lists in tooling.","Validate the rid's room type at the API boundary of integrations."],"tags":["omnichannel","livechat","rooms","room-type","deletion"],"backgroundTag":"invalid-room-type","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}