RocketChat/Rocket.Chat · error · Error
room-closed
Error message
room-closed
What it means
Thrown by POST /livechat/message (message.ts:41-43) when the room exists and belongs to the visitor but room.open is false — the livechat conversation has been closed (by agent, visitor, inactivity auto-close, etc.). Returns HTTP 400 { success:false, error:'room-closed' }.
Source
Thrown at apps/meteor/server/api/v1/omnichannel/message.ts:42
API.v1.addRoute(
'livechat/message',
{ validateParams: isPOSTLivechatMessageParams },
{
async post() {
const { token, rid, agent, msg } = this.bodyParams;
const guest = await findGuest(token);
if (!guest) {
throw new Error('invalid-token');
}
const room = await findRoom(token, rid);
if (!room) {
throw new Error('invalid-room');
}
if (!room.open) {
throw new Error('room-closed');
}
if (
settings.get('Livechat_enable_message_character_limit') &&
msg.length > parseInt(settings.get('Livechat_message_character_limit'))
) {
throw new Error('message-length-exceeds-character-limit');
}
const _id = this.bodyParams._id || Random.id();
const messageToSend = {
guest,
message: {
_id,
rid,
msg,
token,View on GitHub (pinned to f9d3ec372b)
Solutions
- Start a new livechat session / reopen the chat to obtain a new open room before sending.
- Inspect room.open before posting; if closed, prompt the user to begin a new conversation.
- If reopening is supported in your flow, re-open the existing room and retry.
Example fix
// before
POST /livechat/message { token, rid, msg } // room-closed
// after
const room = await findRoom(token, rid);
if (room && !room.open) { /* start new conversation / reopen chat */ }
POST /livechat/message { token, rid, msg } Defensive patterns
Strategy: validation
Validate before calling
const room = await findRoom(token, rid);
if (room && !room.open) {
// start a new conversation / reopen, then retry
throw new Error('room is closed');
}
// safe to POST /livechat/message Type guard
const isRoomOpen = (room: IOmnichannelRoom | null): room is IOmnichannelRoom => !!room && room.open === true;
Try / catch
try { await sendMessage({ token, rid, msg }); }
catch (e) { if (e instanceof Error && e.message === 'room-closed') { /* prompt new conversation */ } else throw e; } Prevention
- Check room.open before sending.
- Treat closed chats as terminal; start a new session instead of hammering retries.
- Surface 'conversation ended' UI on room-closed.
When it happens
Trigger: Sending a message to a livechat room whose `open` flag is false.
Common situations: Chat ended by agent or visitor; auto-close after inactivity timeout; attempting to reply after the session was closed.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/826742716d8d3e5f.
Report an issue: GitHub.