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
- Close the visitor's open rooms first (agent closes chat, or close via the close endpoint/omnichannel APIs), then retry the DELETE
- 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
- 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
- Close or wait out open conversations before running visitor erasure
- Decide deliberately whether the HTTP-header-info setting stays off (blocks delete with open rooms)
- Schedule GDPR deletes outside business hours when chats are closed
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
- error-removing-visitor
- error-action-not-allowed
- error-comment-is-required
- error-invalid-channel
- error-invalid-contact
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)