RocketChat/Rocket.Chat · warning · Meteor.Error

visitor-has-open-rooms

visitor-has-open-rooms

Error message

Cannot remove visitors with opened rooms

What it means

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.

Source

Thrown at apps/meteor/server/api/v1/omnichannel/visitor.ts:144

		const extraQuery = await callbacks.run('livechat.applyRoomRestrictions', {}, { userId: this.userId });
		const rooms = await LivechatRooms.findOpenByVisitorToken(
			this.urlParams.token,
			{
				projection: {
					name: 1,
					t: 1,
					cl: 1,
					u: 1,
					usernames: 1,
					servedBy: 1,
				},
			},
			extraQuery,
		).toArray();

		// if gdpr is enabled, bypass rooms check
		if (rooms?.length && !settings.get('Livechat_Allow_collect_and_store_HTTP_header_informations')) {
			throw new Meteor.Error('visitor-has-open-rooms', 'Cannot remove visitors with opened rooms');
		}

		const { _id } = visitor;
		try {
			await removeContactsByVisitorId({ _id });
			return API.v1.success({
				visitor: {
					_id,
					ts: new Date().toISOString(),
				},
			});
		} catch (e) {
			livechatLogger.error({ msg: 'Error removing visitor', err: e });
			throw new Meteor.Error('error-removing-visitor', 'An error ocurred while deleting visitor');
		}
	},
});

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Close all open rooms for the visitor (set open=false) before deleting.
  2. 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).
  3. Run the deletion through the GDPR/contacts tooling that closes rooms first.

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

const openRooms = await fetch(`/api/v1/v1/livechat/visitor/${token}/room`).then(r => r.json());
if (openRooms.rooms?.length) {
  // close each room (POST livechat/room.close) before deleting the visitor
}

Type guard

null

Try / catch

try { await deleteVisitor(token); } catch (e) { if (e.error === 'visitor-has-open-rooms') { /* close rooms first, then retry */ } }

Prevention

When it happens

Trigger: 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.

Common situations: Operator bulk-cleanup script that deletes visitors without first closing their rooms; misreading the setting name as purely a header-storage toggle.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/a25455dcaf2e4a7f. Report an issue: GitHub.