RocketChat/Rocket.Chat · error · Meteor.Error

visitor-has-open-rooms

visitor-has-open-rooms

Error message

Cannot remove visitors with opened rooms

What it means

Thrown by DELETE /api/v1/livechat/visitor/:token when the visitor still has open (unclosed) livechat rooms and the setting Livechat_Allow_collect_and_store_HTTP_header_informations is DISABLED. Despite its name, that setting doubles as the GDPR-ish bypass: when it is enabled, the open-rooms check is skipped and deletion proceeds. So deletion is blocked only when open rooms exist AND the bypass setting is off.

Solutions

  1. Close the visitor's open rooms first (agent closes chat, or close via the close endpoint/omnichannel APIs), then retry the DELETE
  2. Alternatively enable Administration -> Omnichannel -> Livechat_Allow_collect_and_store_HTTP_header_informations to bypass the open-rooms check — accepting the privacy trade-off its name implies
  3. For bulk erasure, schedule it for after closetimeout/office hours when rooms are naturally closed
Defensive patterns

Strategy: validation

Validate before calling

// with an authenticated admin token, check open rooms first
const rooms = await (await fetch(`${server}/api/v1/livechat/visitor/${encodeURIComponent(token)}/room`, { headers })).json();
if (rooms?.rooms?.length > 0) throw new Error('close open rooms before deleting this visitor');
await fetch(`${server}/api/v1/livechat/visitor/${encodeURIComponent(token)}`, { method: 'DELETE' });

Type guard

const visitorHasNoOpenRooms = (b: { rooms?: unknown[] }): boolean => !Array.isArray(b.rooms) || b.rooms.length === 0;

Try / catch

const body = await (await fetch(url, { method: 'DELETE' })).json();
if (!body.success && body.error === 'visitor-has-open-rooms') { /* close rooms (or enable bypass setting) and retry later */ }

Prevention

When it happens

Trigger: DELETE a visitor who currently has an in-progress chat, a queued room, or an on-hold conversation, while the HTTP-header-info setting is false; visitors whose rooms never closed due to inactivity timeouts being disabled.

Common situations: GDPR erasure automation running while conversations are active; test fixtures deleting visitors without closing their rooms first; ops teams surprised that enabling 'collect HTTP header info' changes deletion behavior.

Related errors


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

Appendix: 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 b2c16d5842)