RocketChat/Rocket.Chat · error · Error
invalid-room
Error message
invalid-room
What it means
Thrown in the GET handler of 'livechat/room' (room.ts:118-121) when LivechatRooms.findOneOpenByRoomIdAndVisitorToken(rid, token, {}) returns null. This executes only when a rid IS provided in the query params (the !rid branch at line 80 handles room creation/lookup without rid). The query finds an OPEN room matching both the rid and the visitor token.
Source
Thrown at apps/meteor/server/api/v1/omnichannel/room.ts:120
},
};
const newRoom = await createRoom({
visitor: guest,
roomInfo,
agent,
extraData: extraParams as IOmnichannelInquiryExtraData,
});
return API.v1.success({
room: newRoom,
newRoom: true,
});
}
const froom = await LivechatRooms.findOneOpenByRoomIdAndVisitorToken(rid, token, {});
if (!froom) {
throw new Error('invalid-room');
}
return API.v1.success({ room: froom, newRoom: false });
},
},
);
// Note: use this route if a visitor is closing a room
// If a RC user(like eg agent) is closing a room, use the `livechat/room.closeByUser` route
API.v1.addRoute(
'livechat/room.close',
{ validateParams: isPOSTLivechatRoomCloseParams },
{
async post() {
const { rid, token } = this.bodyParams;
if (!rcSettings.get('Omnichannel_allow_visitors_to_close_conversation')) {
throw new Error('error-not-allowed-to-close-conversation');View on GitHub (pinned to f9d3ec372b)
Solutions
- Check if the room exists (including closed): db.livechat_rooms.findOne({_id: rid}).
- Check if it belongs to this visitor: db.livechat_rooms.findOne({_id: rid, 'v.token': token}).
- Check if it's open: db.livechat_rooms.findOne({_id: rid, open: true}). If closed, a new room must be created.
- If no rid is provided, the handler will create or find an open room automatically — omit rid to get a new room.
Example fix
// before GET /api/v1/livechat/room?token=X&rid=closedRoomId // throws 'invalid-room' because the room is closed // after — omit rid to let the system find/create an open room GET /api/v1/livechat/room?token=X
Defensive patterns
Strategy: validation
Validate before calling
// Check for an open room before requesting it by rid
const openRoom = await LivechatRooms.findOneOpenByRoomIdAndVisitorToken(rid, token);
if (!openRoom) {
// omit rid to let the system find/create an open room instead
throw new Error(`No open room ${rid} for this visitor — create a new one instead`);
} Type guard
function isOpenRoomForVisitor(room: IOmnichannelRoom | null, token: string): room is IOmnichannelRoom {
return room !== null && room.open === true && room.v?.token === token;
} Try / catch
try {
await api.get(`/livechat/room?token=${token}&rid=${rid}`);
} catch (err) {
if (err.message === 'invalid-room') {
// omit rid to find/create an open room
await api.get(`/livechat/room?token=${token}`);
}
} Prevention
- When a room is closed, omit the rid parameter on the next GET /livechat/room to let the system find or create an open room.
- Check room.open status client-side before requesting by rid.
- Handle closed-room state transitions gracefully — do not assume a rid remains valid after closing.
When it happens
Trigger: Calling GET /api/v1/livechat/room?token=X&rid=Y where no open livechat room with _id=Y is associated with visitor token X. The room may be closed, may not exist, or may belong to a different visitor.
Common situations: The room was already closed by the visitor or an agent; rid is from a different visitor's session; rid was mistyped; the room was deleted. Note this specifically looks for OPEN rooms — a closed room will return null even if it exists.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/aa20d4d7643d3be2.
Report an issue: GitHub.