{"record":{"id":"9b3ee251ec18bd35","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-9b3ee2","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/room.ts","lineNumber":296,"sourceCode":"\n\t\t\treturn API.v1.success({ rid, data: updateData });\n\t\t},\n\t},\n);\n\nAPI.v1.addRoute(\n\t'livechat/room.forward',\n\t{ authRequired: true, permissionsRequired: ['view-l-room', 'transfer-livechat-guest'], validateParams: isLiveChatRoomForwardProps },\n\t{\n\t\tasync post() {\n\t\t\tconst transferData = this.bodyParams as typeof this.bodyParams & {\n\t\t\t\ttransferredBy: TransferByData;\n\t\t\t\ttransferredTo?: { _id: string; username?: string; name?: string };\n\t\t\t};\n\n\t\t\tconst room = await LivechatRooms.findOneById(this.bodyParams.roomId);\n\t\t\tif (room?.t !== 'l') {\n\t\t\t\tthrow new Error('error-invalid-room');\n\t\t\t}\n\n\t\t\tif (!room.open) {\n\t\t\t\tthrow new Error('This_conversation_is_already_closed');\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\tconst guest = await LivechatVisitors.findOneEnabledById(room.v?._id);\n\t\t\tif (!guest) {\n\t\t\t\tthrow new Error('error-invalid-visitor');\n\t\t\t}\n\n\t\t\ttransferData.transferredBy = normalizeTransferredByData(this.user, room);\n\t\t\tif (transferData.userId) {\n\t\t\t\tconst userToTransfer = await Users.findOneById(transferData.userId);","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/omnichannel/room.ts#L278-L314","documentation":"Thrown in the POST handler of 'livechat/room.forward' (room.ts:294-297) when LivechatRooms.findOneById(this.bodyParams.roomId) returns null OR the found room's type field 't' is not 'l' (livechat). This is an authenticated endpoint requiring 'view-l-room' and 'transfer-livechat-guest' permissions. The room must exist and be an omnichannel room.","triggerScenarios":"Calling POST /api/v1/livechat/room.forward with a roomId that either doesn't exist in the database or exists but is not a livechat room (type !== 'l'). For example, forwarding a regular channel, direct message, or a non-existent room ID.","commonSituations":"roomId was mistyped or copied from a non-livechat room; the room was deleted before the forward request; attempting to forward a regular channel or DM (type 'c' or 'd' or 'p'); cross-environment ID mismatch.","solutions":["Verify the room exists and is a livechat room: db.livechat_rooms.findOne({_id: roomId}) — check that field 't' equals 'l'.","Ensure the roomId was obtained from a livechat room listing or creation response.","If the room was deleted, forwarding is not possible."],"exampleFix":"// before\nawait api.post('/livechat/room.forward', { roomId: channelId });\n// throws 'error-invalid-room' — channelId is a regular channel, not livechat\n\n// after — use a valid livechat room ID\nconst livechatRoom = await LivechatRooms.findOne({t: 'l', _id: roomId});\nif (!livechatRoom || livechatRoom.t !== 'l') {\n  throw new Error('Room is not a livechat room');\n}\nawait api.post('/livechat/room.forward', { roomId: livechatRoom._id });","handlingStrategy":"validation","validationCode":"// Verify the room is a livechat room before forwarding\nconst room = await LivechatRooms.findOneById(roomId);\nif (!room || room.t !== 'l') {\n  throw new Error(`Room ${roomId} is not a livechat room or does not exist`);\n}","typeGuard":"function isLivechatRoom(room: IOmnichannelRoom | null): room is IOmnichannelRoom {\n  return room !== null && room.t === 'l';\n}","tryCatchPattern":"try {\n  await api.post('/livechat/room.forward', { roomId, ...transferData });\n} catch (err) {\n  if (err.message === 'error-invalid-room') {\n    // verify room exists and is livechat type, then retry or inform user\n    const room = await getRoomById(roomId);\n    if (!room || room.t !== 'l') {\n      throw new Error('Cannot forward: room is not a livechat room');\n    }\n  }\n}","preventionTips":["Verify the room type is 'l' (livechat) before calling the forward endpoint.","Obtain roomId only from livechat room listings or creation responses.","Do not reuse room IDs from regular channels or DMs for livechat operations.","Ensure the room has not been deleted before forwarding — check existence first."],"tags":["omnichannel","room","type-mismatch","validation","room-forward"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}