{"record":{"id":"0924bbc83fea6167","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-0924bb","errorCode":null,"errorMessage":"error-invalid-room","messagePattern":"error-invalid-room","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/transcript.ts","lineNumber":42,"sourceCode":"\nAPI.v1.addRoute(\n\t'livechat/transcript/:rid',\n\t{\n\t\tauthRequired: true,\n\t\tpermissionsRequired: ['send-omnichannel-chat-transcript'],\n\t\tvalidateParams: {\n\t\t\tPOST: isPOSTLivechatTranscriptRequestParams,\n\t\t},\n\t},\n\t{\n\t\tasync delete() {\n\t\t\tconst { rid } = this.urlParams;\n\t\t\tconst room = await LivechatRooms.findOneById<Pick<IOmnichannelRoom, 'open' | 'transcriptRequest' | 'v'>>(rid, {\n\t\t\t\tprojection: { open: 1, transcriptRequest: 1, v: 1 },\n\t\t\t});\n\n\t\t\tif (!room?.open) {\n\t\t\t\tthrow new Error('error-invalid-room');\n\t\t\t}\n\t\t\tif (!room.transcriptRequest) {\n\t\t\t\tthrow new Error('error-transcript-not-requested');\n\t\t\t}\n\n\t\t\tif (!(await Omnichannel.isWithinMACLimit(room))) {\n\t\t\t\tthrow new Error('error-mac-limit-reached');\n\t\t\t}\n\n\t\t\tawait LivechatRooms.unsetEmailTranscriptRequestedByRoomId(rid);\n\n\t\t\treturn API.v1.success();\n\t\t},\n\t\tasync post() {\n\t\t\tconst { rid } = this.urlParams;\n\t\t\tconst { email, subject } = this.bodyParams;\n\n\t\t\tconst user = await Users.findOneById(this.userId, {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/v1/omnichannel/transcript.ts#L24-L60","documentation":"Thrown by DELETE /api/v1/livechat/transcript/:rid when the room does not exist OR is not open (the check is !room?.open). You can only cancel a transcript request on a currently open livechat room. A closed room, a nonexistent rid, or a malformed rid all produce this error.","triggerScenarios":"DELETE /api/v1/livechat/transcript/<rid> after the conversation was closed (by agent, visitor, or inactivity); using an rid from the wrong environment; typos in the room id; calling delete twice after the room closed between calls.","commonSituations":"Race where the chat closes while your integration is mid-flow (visitor left, room closed by closetimeout); stale rid captured from an earlier test run against a re-seeded database.","solutions":["Fetch the room first (e.g. GET /api/v1/livechat/rooms and match on rid, or livechat room endpoints) and confirm it is open before deleting the transcript request","If the room already closed, there is nothing to cancel — treat this as success in your flow","Double-check the rid is the full room id from the same workspace"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const room = await (await fetch(`${server}/api/v1/livechat/room/${rid}`, { headers })).json();\nif (!room?.room?.open) skipTranscriptCancel(); // deleting requires an OPEN room","typeGuard":"const isOpenRoom = (r: unknown): r is { _id: string; open: true } =>\n  !!r && typeof r === 'object' && (r as any).open === true;","tryCatchPattern":"const body = await (await fetch(`${server}/api/v1/livechat/transcript/${rid}`, { method: 'DELETE', headers })).json();\nif (!body.success && body.error === 'error-invalid-room') { /* room missing/closed: treat cancel as done */ }","preventionTips":["Refresh room state immediately before transcript operations","Treat closed-room cancellations as no-ops, not failures, in automation"],"tags":["rest-api","livechat","transcript","room-state","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"}