{"record":{"id":"4537df5175240624","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-4537df","errorCode":"error-invalid-room","errorMessage":"error-invalid-room","messagePattern":"error-invalid-room","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/omnichannel/sendTranscript.ts","lineNumber":49,"sourceCode":"\nexport async function sendTranscript({\n\ttoken,\n\trid,\n\temail,\n\tsubject,\n\tuser,\n}: {\n\ttoken: string;\n\trid: string;\n\temail: string;\n\tsubject?: string;\n\tuser?: Pick<IUser, '_id' | 'name' | 'username' | 'utcOffset'> | null;\n}): Promise<boolean> {\n\tlogger.debug({ msg: 'Sending conversation transcript', rid, token });\n\n\tconst room = await LivechatRooms.findOneById<Pick<IOmnichannelRoom, '_id' | 'v'>>(rid, { projection: { _id: 1, v: 1 } });\n\tif (!room) {\n\t\tthrow new Error('error-invalid-room');\n\t}\n\n\tconst visitor = room?.v as ILivechatVisitor;\n\tif (token !== visitor?.token) {\n\t\tthrow new Error('error-invalid-visitor');\n\t}\n\n\tconst userLanguage = settings.get<string>('Language') || 'en';\n\tconst timezone = getTimezone(user);\n\tlogger.debug({ msg: 'Transcript will be sent using timezone', timezone });\n\n\tconst showAgentInfo = settings.get<boolean>('Livechat_show_agent_info');\n\tconst showSystemMessages = settings.get<boolean>('Livechat_transcript_show_system_messages');\n\tconst closingMessage = await Messages.findLivechatClosingMessage(rid, { projection: { ts: 1 } });\n\tconst ignoredMessageTypes: MessageTypesValues[] = [\n\t\t'livechat_navigation_history',\n\t\t'livechat_transcript_history',\n\t\t'command',","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/omnichannel/sendTranscript.ts#L31-L67","documentation":"Thrown by sendTranscript in apps/meteor/server/lib/omnichannel/sendTranscript.ts when LivechatRooms.findOneById(rid) returns null. Only livechat (omnichannel) rooms live in the LivechatRooms collection, so a missing document means the rid either does not exist or is not a livechat room. It is a plain Error (not Meteor.Error) with the code as its message.","triggerScenarios":"Calling sendTranscript({ rid, token, email }) with a rid that has no document in LivechatRooms: a typo'd id, a regular channel id, a room that was already deleted, or a race where the room was removed right before the call.","commonSituations":"Passing a channel/group id instead of the livechat room id from the widget, transcript requested after the room was purged by retention/cleanup jobs, or truncated/copied ids in integrations.","solutions":["Log/verify the rid passed to sendTranscript and confirm it is an omnichannel room id (t: 'l')","Check the room still exists: db.rocketchat_room.findOne({_id: rid, t: 'l'})","If the room was deleted, the transcript cannot be produced from room data — regenerate from message history only if you keep backups","Fix the caller (widget/integration) to pass the rid returned by the livechat room creation API"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { LivechatRooms } from '@rocket.chat/models';\n\nconst room = await LivechatRooms.findOneById(rid, { projection: { _id: 1, v: 1 } });\nif (!room) {\n  // fail early with your own error instead of error-invalid-room deep in sendTranscript\n  throw new Error(`no livechat room ${rid}`);\n}\nawait sendTranscript({ rid, token, email, room });","typeGuard":"function isLivechatRoom(v: { t?: string } | null | undefined): v is { _id: string; t: 'l'; v: { token: string } } {\n  return !!v && v.t === 'l' && typeof v.v?.token === 'string';\n}","tryCatchPattern":"try {\n  await sendTranscript({ rid, token, email });\n} catch (err) {\n  if (err instanceof Error && err.message === 'error-invalid-room') {\n    // room missing: surface a user-facing 'conversation not found' and stop\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always source the rid from the livechat room-creation/visitor APIs rather than user input","Treat error-invalid-room as permanent — do not retry; fix the id instead","In integrations, validate rid shape and existence before the transcript call"],"tags":["omnichannel","transcript","validation","room-not-found"],"backgroundTag":"entity-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}