RocketChat/Rocket.Chat · error · Error

error-contact-has-open-rooms

error-contact-has-open-rooms

Error message

error-contact-has-open-rooms

What it means

Before wiping a contact's data, disableContactById checks for open rooms via LivechatRooms.checkContactOpenRooms; if any exist and the setting 'Livechat_Allow_collect_and_store_HTTP_header_informations' is false, it throws Error('error-contact-has-open-rooms'). That historically unrelated setting doubles as the override switch that allows disabling a contact even while it has open conversations.

Source

Thrown at apps/meteor/server/lib/omnichannel/contacts/disableContact.ts:16

import type { ILivechatContact } from '@rocket.chat/core-typings';
import { LivechatContacts, LivechatRooms } from '@rocket.chat/models';

import { settings } from '../../../settings';
import { removeGuest } from '../guests';

export async function disableContactById(contactId: string): Promise<void> {
	const contact = await LivechatContacts.findOneEnabledById<Pick<ILivechatContact, '_id' | 'channels'>>(contactId);
	if (!contact) {
		throw new Error('error-contact-not-found');
	}

	// Checking if the contact has any open channel/room before removing its data.
	const contactOpenRooms = await LivechatRooms.checkContactOpenRooms(contactId);
	if (contactOpenRooms && !settings.get<boolean>('Livechat_Allow_collect_and_store_HTTP_header_informations')) {
		throw new Error('error-contact-has-open-rooms');
	}

	// Cleaning contact/visitor data;
	await Promise.all(contact.channels.map((channel) => removeGuest({ _id: channel.visitor.visitorId })));

	await LivechatContacts.disableByContactId(contactId);
}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Close (or wait for auto-close of) all open rooms on the contact's channels, then retry the disable
  2. Enable 'Livechat_Allow_collect_and_store_HTTP_header_informations' to permit disabling contacts with open rooms (force behavior)
  3. Tighten omnichannel inactivity auto-close so stale open rooms stop blocking contact deletions
Defensive patterns

Strategy: validation

Validate before calling

import { LivechatRooms } from '@rocket.chat/models';
import { settings } from '../../../settings/server';

const hasOpen = await LivechatRooms.checkContactOpenRooms(contactId);
if (hasOpen && !settings.get<boolean>('Livechat_Allow_collect_and_store_HTTP_header_informations')) {
  // close the contact's open rooms first (or wait for auto-close) before disabling
}

Try / catch

try {
  await disableContactById(contactId);
} catch (err: any) {
  if (err?.message === 'error-contact-has-open-rooms') {
    await closeOpenRoomsForContact(contactId);
    return disableContactById(contactId); // retry once the rooms are closed
  }
  throw err;
}

Prevention

When it happens

Trigger: Disabling a contact whose visitor still has an open livechat conversation on any of its channels, without the override setting enabled; the deletion guard fires before any guest data is removed.

Common situations: GDPR/privacy erasure jobs hitting contacts mid-conversation; abandoned-but-open chats that inactivity auto-close never expired; admins unaware that the HTTP-header setting acts as the force flag here.

Related errors


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