{"record":{"id":"cff578c9e08c1c73","repo":"RocketChat/Rocket.Chat","slug":"room-id-not-found","errorCode":null,"errorMessage":"Room id not found","messagePattern":"Room id not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/rooms.ts","lineNumber":239,"sourceCode":"\n\tprotected async getDirectByUsernames(usernames: Array<string>, appId: string): Promise<IRoom | undefined> {\n\t\tthis.orch.debugLog(`The App ${appId} is getting direct room by usernames: \"${usernames}\"`);\n\t\tconst room = await Rooms.findDirectRoomContainingAllUsernames(usernames, {});\n\t\tif (!room) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.orch.getConverters()?.get('rooms').convertRoom(room);\n\t}\n\n\tprotected async update(room: IRoom, members: Array<string> = [], appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is updating a room.`);\n\n\t\tconst rm = await this.orch.getConverters()?.get('rooms').convertAppRoom(room, true);\n\n\t\tconst updateResult = await Rooms.updateOne({ _id: room.id }, { $set: rm });\n\n\t\tif (!updateResult.matchedCount) {\n\t\t\tthrow new Error('Room id not found');\n\t\t}\n\n\t\tfor (const username of members) {\n\t\t\tconst member = await Users.findOneByUsername(username, {});\n\n\t\t\tif (!member) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tawait addUserToRoom(room.id, member);\n\t\t}\n\t}\n\n\tprotected async delete(roomId: string, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is deleting a room.`);\n\t\tawait deleteRoom(roomId);\n\t}\n","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/app/apps/server/bridges/rooms.ts#L221-L257","documentation":"Thrown by AppRoomBridge.update when Rooms.updateOne({_id: room.id}, {$set: rm}) reports matchedCount === 0. The bridge converts the App's IRoom to a raw room, runs the update, and treats zero matches as 'the room does not exist'. Member additions are skipped because the throw precedes the members loop.","triggerScenarios":"An App calls the rooms accessor's update with a room whose id does not correspond to any persisted room document — a deleted room, a fabricated id, a room on another workspace, or an id extracted from a stale/federated reference that has no local document.","commonSituations":"Updating a room from a cached IRoom after it was deleted; federation or cross-workspace ids; acting on a webhook for a room that was archived; passing room.id from an object whose id field was never populated.","solutions":["Verify the room exists (getById) before calling update, and surface a clear error to the user if not.","Refresh the IRoom from the accessor before updating so room.id is current.","If the room may have been deleted, treat matchedCount 0 as a recoverable case in your App's logic rather than propagating the bridge error."],"exampleFix":"// before\nawait rooms.update(staleRoom, members, appId);\n\n// after\nconst existing = await rooms.getById(staleRoom.id, appId);\nif (!existing) throw new Error(`Room ${staleRoom.id} no longer exists`);\nawait rooms.update(staleRoom, members, appId);","handlingStrategy":"validation","validationCode":"const existing = await rooms.getById(room.id, appId);\nif (!existing) {\n  throw new Error(`Cannot update: room ${room.id} does not exist`);\n}\nawait rooms.update(room, members, appId);","typeGuard":null,"tryCatchPattern":"try {\n  await rooms.update(room, members, appId);\n} catch (e) {\n  if (e instanceof Error && /Room id not found/.test(e.message)) {\n    this.app.getLogger().warn({ msg: 'Room disappeared before update', roomId: room.id });\n    return; // or recreate / re-fetch\n  }\n  throw e;\n}","preventionTips":["Refresh the IRoom from the accessor before updating so room.id is current.","Verify the room exists with getById before attempting an update.","Treat matchedCount 0 as a recoverable case (room deleted/archived) in your App logic."],"tags":["apps-engine","room-bridge","validation","room-id","matched-count","not-found"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}