{"record":{"id":"0924bbc83fea6167","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-0924bb","errorCode":"error-invalid-room","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/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/omnichannel/transcript.ts#L24-L60","documentation":"Thrown by DELETE livechat/transcript/:rid when the room lookup returns null OR room.open is false. The endpoint cancels a previously-requested email transcript; cancellation only makes sense on an open conversation, so a missing or already-closed room is rejected before checking whether a transcript was requested.","triggerScenarios":"DELETE /api/v1/livechat/transcript/<rid> against a room id that does not exist, or whose open flag is false. The projection only fetches open, transcriptRequest, v, so a closed room reaches this guard.","commonSituations":"User clicks 'cancel transcript' on a room that was just closed by the agent/inactivity; client holds a stale rid; race between close and the cancel click; transcript request was on a room that has since been deleted.","solutions":["Check room.open before offering the cancel-transcript action in the UI.","If the room closed naturally, the transcript request is moot — no cancel needed; inform the user.","Refresh the room state before issuing DELETE if the action has been pending in the UI.","Handle this error gracefully as 'no action needed' rather than an error toast."],"exampleFix":"// before\nawait DELETE('/api/v1/livechat/transcript/' + rid);\n\n// after\nconst room = await fetchRoom(rid);\nif (!room?.open) { notify('Room closed - transcript request cleared on close'); return; }\nawait DELETE('/api/v1/livechat/transcript/' + rid);","handlingStrategy":"validation","validationCode":"const room = await LivechatRooms.findOneById(rid, { projection: { open: 1, transcriptRequest: 1 } });\nif (!room?.open) throw new ClientError('room-closed-or-missing');","typeGuard":"const isOpenForTranscript = (r: { open?: boolean; transcriptRequest?: unknown } | null): r is { open: true; transcriptRequest: unknown } =>\n  !!r && r.open === true;","tryCatchPattern":"try {\n  await DELETE('/api/v1/livechat/transcript/' + rid);\n} catch (e) {\n  if (e.message === 'error-invalid-room') { notify('Room is closed - nothing to cancel'); return; }\n  throw e;\n}","preventionTips":["Only show the cancel-transcript control when room.open === true.","Clear transcript-requested UI state when the room closes.","Treat a closed-room cancel as a no-op, not an error."],"tags":["omnichannel","livechat","transcript","room-state","validation"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}