{"record":{"id":"a25455dcaf2e4a7f","repo":"RocketChat/Rocket.Chat","slug":"visitor-has-open-rooms","errorCode":"visitor-has-open-rooms","errorMessage":"Cannot remove visitors with opened rooms","messagePattern":"Cannot remove visitors with opened rooms","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"warning","filePath":"apps/meteor/server/api/v1/omnichannel/visitor.ts","lineNumber":144,"sourceCode":"\t\tconst extraQuery = await callbacks.run('livechat.applyRoomRestrictions', {}, { userId: this.userId });\n\t\tconst rooms = await LivechatRooms.findOpenByVisitorToken(\n\t\t\tthis.urlParams.token,\n\t\t\t{\n\t\t\t\tprojection: {\n\t\t\t\t\tname: 1,\n\t\t\t\t\tt: 1,\n\t\t\t\t\tcl: 1,\n\t\t\t\t\tu: 1,\n\t\t\t\t\tusernames: 1,\n\t\t\t\t\tservedBy: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\textraQuery,\n\t\t).toArray();\n\n\t\t// if gdpr is enabled, bypass rooms check\n\t\tif (rooms?.length && !settings.get('Livechat_Allow_collect_and_store_HTTP_header_informations')) {\n\t\t\tthrow new Meteor.Error('visitor-has-open-rooms', 'Cannot remove visitors with opened rooms');\n\t\t}\n\n\t\tconst { _id } = visitor;\n\t\ttry {\n\t\t\tawait removeContactsByVisitorId({ _id });\n\t\t\treturn API.v1.success({\n\t\t\t\tvisitor: {\n\t\t\t\t\t_id,\n\t\t\t\t\tts: new Date().toISOString(),\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tlivechatLogger.error({ msg: 'Error removing visitor', err: e });\n\t\t\tthrow new Meteor.Error('error-removing-visitor', 'An error ocurred while deleting visitor');\n\t\t}\n\t},\n});\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/omnichannel/visitor.ts#L126-L162","documentation":"Thrown as Meteor.Error('visitor-has-open-rooms', 'Cannot remove visitors with opened rooms') on DELETE livechat/visitor/:token when the visitor has one or more open rooms AND the Livechat_Allow_collect_and_store_HTTP_header_informations setting is false. The setting name is misleading: the code uses it as a stand-in for 'GDPR bypass enabled', which skips the open-rooms safeguard.","triggerScenarios":"Deleting a visitor that still has open omnichannel conversations while the GDPR/header-collection setting is off. The rooms check is bypassed only when that setting is true.","commonSituations":"Operator bulk-cleanup script that deletes visitors without first closing their rooms; misreading the setting name as purely a header-storage toggle.","solutions":["Close all open rooms for the visitor (set open=false) before deleting.","If your workflow intentionally forces deletion of visitors with open rooms, enable Livechat_Allow_collect_and_store_HTTP_header_informations (understand it also enables header data collection).","Run the deletion through the GDPR/contacts tooling that closes rooms first."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"const openRooms = await fetch(`/api/v1/v1/livechat/visitor/${token}/room`).then(r => r.json());\nif (openRooms.rooms?.length) {\n  // close each room (POST livechat/room.close) before deleting the visitor\n}","typeGuard":"null","tryCatchPattern":"try { await deleteVisitor(token); } catch (e) { if (e.error === 'visitor-has-open-rooms') { /* close rooms first, then retry */ } }","preventionTips":["Always close a visitor's open rooms before deletion.","Understand that Livechat_Allow_collect_and_store_HTTP_header_informations toggles the bypass, despite its name.","Use GDPR tooling that handles the close-then-delete order."],"tags":["omnichannel","visitor","delete","open-rooms","settings","gdpr"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}