{"record":{"id":"8f3b570a950fd888","repo":"RocketChat/Rocket.Chat","slug":"invalid-room-8f3b57","errorCode":null,"errorMessage":"invalid-room","messagePattern":"invalid-room","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/transfer.ts","lineNumber":16,"sourceCode":"import { LivechatRooms } from '@rocket.chat/models';\n\nimport { API } from '../..';\nimport { findLivechatTransferHistory } from './lib/transfer';\nimport { getPaginationItems } from '../../lib/getPaginationItems';\n\nAPI.v1.addRoute(\n\t'livechat/transfer.history/:rid',\n\t{ authRequired: true, permissionsRequired: ['view-livechat-rooms'] },\n\t{\n\t\tasync get() {\n\t\t\tconst { rid } = this.urlParams;\n\n\t\t\tconst room = await LivechatRooms.findOneById(rid, { projection: { _id: 1 } });\n\t\t\tif (!room) {\n\t\t\t\tthrow new Error('invalid-room');\n\t\t\t}\n\t\t\tconst { offset, count } = await getPaginationItems(this.queryParams);\n\t\t\tconst { sort } = await this.parseJsonQuery();\n\n\t\t\tconst history = await findLivechatTransferHistory({\n\t\t\t\trid,\n\t\t\t\tpagination: {\n\t\t\t\t\toffset,\n\t\t\t\t\tcount,\n\t\t\t\t\tsort,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn API.v1.success(history);\n\t\t},\n\t},\n);\n","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/v1/omnichannel/transfer.ts#L1-L34","documentation":"Thrown by GET /api/v1/livechat/transfer.history/:rid when no livechat room exists with the given rid (projection {_id: 1} returns nothing). It is a plain not-found guard before paging through the room's transfer history; requires the view-livechat-rooms permission.","triggerScenarios":"GET /api/v1/livechat/transfer.history/<wrong-or-closed-then-deleted-rid>; rid copied with trailing whitespace or quotes; room id from another workspace/environment; room deleted by retention.","commonSituations":"Integrations that cache rids across environments (dev vs prod); retention policies removing old livechat rooms while analytics exports still reference them; URL encoding issues mangling the id.","solutions":["Verify the rid exists first via GET /api/v1/livechat/rooms (filter by roomName) or wherever you obtained it","Trim/validate the rid format before calling (Rocket.Chat ids are 17-char alphanumeric)","If rooms are being retention-deleted, capture transfer history before retention runs"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const exists = await (await fetch(`${server}/api/v1/livechat/rooms?roomName=${encodeURIComponent(name)}`, { headers })).json();\nconst rid = exists?.rooms?.[0]?._id;\nif (rid) await fetch(`${server}/api/v1/livechat/transfer.history/${rid}`, { headers });","typeGuard":"const isRocketChatId = (id: unknown): id is string => typeof id === 'string' && /^[A-Za-z0-9]{17}$/.test(id);","tryCatchPattern":"const body = await (await fetch(url, { headers })).json();\nif (!body.success && body.error === 'invalid-room') { /* drop cached rid, re-resolve room, or skip */ }","preventionTips":["Never hardcode rids across environments — resolve them at runtime","Validate the 17-char id shape before building the URL"],"tags":["rest-api","livechat","transfer-history","room-not-found","validation"],"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"}