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
- Verify the room exists first (LivechatRooms.findOneById or the room info REST endpoint) before closing
- Respond with a not-found outcome to the caller - this error is not transient, do not retry
- Confirm the client is pointed at the correct workspace/database (URL and credentials)
- 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
- Take room ids only from prior API responses, never construct them manually
- Validate rid shape/length before calling close endpoints
- Design close flows idempotently: a missing room means nothing left to close
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
- error-room-does-not-exist
- error-invalid-room
- invalid-room
- error-contact-not-found
- error-visitor-not-found
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/e75f402cd7c94d79.
Report an issue: GitHub.