RocketChat/Rocket.Chat · error · Error

error-invalid-room

error-invalid-room

Error message

error-invalid-room

What it means

closeLivechatRoom loads the room by id from LivechatRooms and throws Error('error-invalid-room') when no document matches. It means the roomId handed to the close flow does not exist in this database at all - it is not the 'already closed' or 'wrong room type' signal (those have their own codes).

Source

Thrown at apps/meteor/server/lib/omnichannel/closeLivechatRoom.ts:34

		forceClose = false,
	}: {
		comment?: string;
		tags?: string[];
		generateTranscriptPdf?: boolean;
		transcriptEmail?:
			| {
					sendToVisitor: false;
			  }
			| {
					sendToVisitor: true;
					requestData: Pick<NonNullable<IOmnichannelRoom['transcriptRequest']>, 'email' | 'subject'>;
			  };
		forceClose?: boolean;
	},
): Promise<void> => {
	const room = await LivechatRooms.findOneById(roomId);
	if (!room) {
		throw new Error('error-invalid-room');
	}

	const subscription = await Subscriptions.findOneByRoomIdAndUserId(roomId, user._id, { projection: { _id: 1 } });
	if (!subscription && !(await hasPermissionAsync(user, 'close-others-livechat-room'))) {
		throw new Error('error-not-authorized');
	}

	const options: CloseRoomParams['options'] = {
		clientAction: true,
		tags,
		...(generateTranscriptPdf && { pdfTranscript: { requestedBy: user._id } }),
		...(transcriptEmail && {
			...(transcriptEmail.sendToVisitor
				? {
						emailTranscript: {
							sendToVisitor: true,
							requestData: {
								email: transcriptEmail.requestData.email,

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the room exists first (LivechatRooms.findOneById or the room info REST endpoint) before closing
  2. Respond with a not-found outcome to the caller - this error is not transient, do not retry
  3. Confirm the client is pointed at the correct workspace/database (URL and credentials)
  4. If a parallel flow may have removed the room, treat 'invalid room' as already-closed for idempotency
Defensive patterns

Strategy: validation

Validate before calling

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

const room = await LivechatRooms.findOneById(roomId);
if (!room) {
  // do not call closeLivechatRoom - respond 404 or treat as already removed
}

Type guard

import { isOmnichannelRoom } from '@rocket.chat/core-typings';

const isExistingOmnichannelRoom = (room: any): room is IOmnichannelRoom =>
  !!room && isOmnichannelRoom(room);

Try / catch

try {
  await closeLivechatRoom(roomId, user, { clientAction: true });
} catch (err: any) {
  if (err?.message === 'error-invalid-room') return respondNotFound(roomId);
  throw err;
}

Prevention

When it happens

Trigger: Calling closeLivechatRoom (agent close action, REST/method close with a wrong or expired room id), referencing a room from another workspace, or a truncated/typo'd rid in the payload; also possible when a parallel cleanup (e.g. contact removal) deleted the room doc.

Common situations: Stale client-side rid after a workspace reset or restore; integrations composing room ids by hand instead of using ids from API responses; environment drift where the client talks to the wrong workspace.

Related errors


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