{"record":{"id":"a81eed22104211ae","repo":"RocketChat/Rocket.Chat","slug":"invalid-room-a81eed","errorCode":"invalid-room","errorMessage":"invalid-room","messagePattern":"invalid-room","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/visitors.ts","lineNumber":178,"sourceCode":"\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t},\n);\n\nAPI.v1.addRoute(\n\t'livechat/:rid/messages',\n\t{ authRequired: true, permissionsRequired: ['view-l-room'], validateParams: isLivechatRidMessagesProps },\n\t{\n\t\tasync get() {\n\t\t\tconst { offset, count } = await getPaginationItems(this.queryParams);\n\t\t\tconst { sort } = await this.parseJsonQuery();\n\t\t\tconst { searchTerm } = this.queryParams;\n\n\t\t\tconst room = await LivechatRooms.findOneById(this.urlParams.rid);\n\n\t\t\tif (!room) {\n\t\t\t\tthrow new Error('invalid-room');\n\t\t\t}\n\n\t\t\tif (!(await canAccessRoomAsync(room, this.user))) {\n\t\t\t\tthrow new Error('not-allowed');\n\t\t\t}\n\n\t\t\tconst { cursor, totalCount } = Messages.findLivechatClosedMessages(this.urlParams.rid, searchTerm, {\n\t\t\t\tsort: sort || { ts: -1 },\n\t\t\t\tskip: offset,\n\t\t\t\tlimit: count,\n\t\t\t});\n\n\t\t\tconst [messages, total] = await Promise.all([cursor.toArray(), totalCount]);\n\n\t\t\treturn API.v1.success({\n\t\t\t\tmessages: await normalizeMessagesForUser(messages, this.userId),\n\t\t\t\toffset,\n\t\t\t\tcount,","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/2a7de457074cbb4d4373fbd9a4e5bea292c9c764/apps/meteor/server/api/v1/omnichannel/visitors.ts#L160-L196","documentation":"Thrown by GET /api/v1/livechat/:rid/messages (requires auth plus the view-l-room permission) when LivechatRooms.findOneById(rid) returns null — the URL segment is not the _id of an existing livechat room. The endpoint lists a livechat room's closed/session messages, so passing a regular channel/group rid, a deleted room's rid, or a malformed id fails this lookup before any access check runs.","triggerScenarios":"GET /api/v1/livechat/<rid>/messages where rid is a typo'd or truncated 17-char id, the _id of a normal channel or private group instead of a livechat room, or the id of a livechat room that was deleted (retention/pruning or omnichannel cleanup).","commonSituations":"Reusing rids captured in a different environment; copy-pasting a message id or visitor token into the rid slot; room disappeared between listing it and fetching messages; code that assumes any room id works for livechat endpoints.","solutions":["Source rids only from livechat APIs: GET /api/v1/livechat/rooms (agent view) or the visitor's own history endpoints, never channels.list","Sanity-check the rid shape before calling — Rocket.Chat ids are 17-character alphanumeric strings","If rooms can vanish underneath you (retention), catch this error and drop the rid from your cache instead of retrying"],"exampleFix":"// before\nconst { messages } = await sdk.get(`livechat/${rid}/messages`);\n\n// after (validate rid shape, then call)\nif (!/^[A-Za-z0-9]{17}$/.test(rid)) throw new Error(`malformed rid: ${rid}`);\nconst { messages } = await sdk.get(`livechat/${rid}/messages`);","handlingStrategy":"validation","validationCode":"const isValidRid = (rid: string) => /^[A-Za-z0-9]{17}$/.test(rid);\nif (!isValidRid(rid)) throw new Error(`malformed rid: ${JSON.stringify(rid)}`);\n// prefer sourcing rids from livechat data:\nconst { rooms } = await sdk.get('livechat/rooms', { count: 1 }); // rooms the agent can access","typeGuard":"const isLivechatRoomId = (rid: unknown): rid is string =>\n  typeof rid === 'string' && /^[A-Za-z0-9]{17}$/.test(rid);","tryCatchPattern":"catch error 'invalid-room' and evict the rid from your local cache/queue — the room is gone or was never a livechat room; retrying with the same id cannot succeed.","preventionTips":["Only accept rids from livechat endpoints (livechat/rooms, visitor history)","Validate the 17-char id shape before every call","When retention deletes rooms, expect stale rids and handle removal gracefully"],"tags":["omnichannel","livechat","room","rest-api","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"2a7de457074cbb4d4373fbd9a4e5bea292c9c764","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}