{"record":{"id":"4afe020f1f633167","repo":"RocketChat/Rocket.Chat","slug":"invalid-room-4afe02","errorCode":null,"errorMessage":"invalid-room","messagePattern":"invalid-room","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/lib/visitors.ts","lineNumber":28,"sourceCode":"\tif (!visitor) {\n\t\tthrow new Error('visitor-not-found');\n\t}\n\n\treturn {\n\t\tvisitor,\n\t};\n}\n\nexport async function findVisitedPages({\n\troomId,\n\tpagination: { offset, count, sort },\n}: {\n\troomId: IRoom['_id'];\n\tpagination: { offset: number; count: number; sort: FindOptions<IMessage>['sort'] };\n}) {\n\tconst room = await LivechatRooms.findOneById(roomId);\n\tif (!room) {\n\t\tthrow new Error('invalid-room');\n\t}\n\tconst { cursor, totalCount } = Messages.findPaginatedByRoomIdAndType(room._id, 'livechat_navigation_history', {\n\t\tsort: sort || { ts: -1 },\n\t\tskip: offset,\n\t\tlimit: count,\n\t});\n\n\tconst [pages, total] = await Promise.all([cursor.toArray(), totalCount]);\n\n\treturn {\n\t\tpages,\n\t\tcount: pages.length,\n\t\toffset,\n\t\ttotal,\n\t};\n}\n\nexport async function findChatHistory({","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/v1/omnichannel/lib/visitors.ts#L10-L46","documentation":"findVisitedPages (backing GET /api/v1/livechat/visitors.pagesHistory/:roomId) first resolves LivechatRooms.findOneById(roomId); when no room document with that _id exists it throws 'invalid-room' before querying navigation-history messages.","triggerScenarios":"Calling pagesHistory with a mistyped rid, a room id from another workspace, or a room whose document was deleted (e.g. by retention/pruning) while its messages or client state lingered.","commonSituations":"Rid captured from an old chat URL or export; room removed by cleanup jobs; client state referencing a room after the visitor re-registered with a new room.","solutions":["Use the rid exactly as returned by the room/message APIs for the same environment.","If the room was deleted, treat visited pages as gone and render an empty history.","Sanity-check the id (24-hex Mongo ObjectId format) before calling to catch truncation/copy errors."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const OBJ_ID = /^[0-9a-f]{24}$/i;\nif (!OBJ_ID.test(roomId)) throw new TypeError('malformed roomId');\n// If in doubt, confirm the room exists first (rooms.info or an equivalent room lookup you already use)\nconst room = await getRoomById(roomId);\nif (!room) return { pages: [], total: 0 }; // deleted room -> no navigation history\nreturn getVisitedPages(roomId, pagination);","typeGuard":null,"tryCatchPattern":"try { return await findVisitedPages({ roomId, pagination }); } catch (e) { if (e.message === 'invalid-room') return { pages: [], count: 0, offset: pagination.offset, total: 0 }; throw e; }","preventionTips":["Use rids straight from room/message payloads of the same environment.","Treat invalid-room on history endpoints as empty history, not an error page.","Validate ObjectId shape before calling to catch copy truncation."],"tags":["omnichannel","visitors","navigation-history","room","rest-api"],"backgroundTag":"resource-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}