RocketChat/Rocket.Chat · error · Error
invalid-room
Error message
invalid-room
What it means
Thrown by POST /livechat/message (message.ts:36-39) when findRoom(token, rid) returns null. findRoom (livechat.ts:59-74) looks the room up by id AND visitor token (findOneByIdAndVisitorToken), so null means either the room does not exist or it does not belong to the visitor owning `token`. Returns HTTP 400 { success:false, error:'invalid-room' }.
Source
Thrown at apps/meteor/server/api/v1/omnichannel/message.ts:38
import { settings } from '../../../settings';
import { getPaginationItems } from '../../lib/getPaginationItems';
import { isWidget } from '../../lib/isWidget';
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: {View on GitHub (pinned to f9d3ec372b)
Solutions
- Ensure rid belongs to the visitor that owns `token` (use the rid returned by room creation).
- Pre-verify with findRoom(token, rid); if null, create/open a new room for the visitor.
- Confirm rid is the livechat room `_id`, not its name or a message id.
Example fix
// before
POST /livechat/message { token, rid: cachedRid, msg } // throws invalid-room after re-register
// after
const room = await findRoom(token, rid);
if (!room) { /* open a new room for this visitor first */ }
POST /livechat/message { token, rid: room._id, msg } Defensive patterns
Strategy: validation
Validate before calling
const room = await findRoom(token, rid);
if (!room) {
// open a new room for this visitor, then retry
throw new Error('room not found for this visitor token');
}
// safe to POST /livechat/message Type guard
const roomBelongsToVisitor = async (token: string, rid: string) =>
!!(await LivechatRooms.findOneByIdAndVisitorToken(rid, token, { projection: { _id: 1 } })); Try / catch
try { await sendMessage({ token, rid, msg }); }
catch (e) { if (e instanceof Error && e.message === 'invalid-room') { /* open new room, retry */ } else throw e; } Prevention
- Keep token and rid as a pair from the same session.
- After re-registering a visitor, open a fresh room rather than reusing an old rid.
When it happens
Trigger: POST /livechat/message with a rid that does not exist, belongs to a different visitor/token, or is the wrong kind of id.
Common situations: Reused rid after visitor re-registration (new token no longer matches the old room); typo; passing the room name or a messageId as rid.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/b4b1ad0c59b0a3ed.
Report an issue: GitHub.