{"record":{"id":"6830f5a6a4e835d1","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-6830f5","errorCode":"error-invalid-room","errorMessage":"Invalid room","messagePattern":"Invalid room","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/eraseRoom.ts","lineNumber":15,"sourceCode":"import { AppEvents, Apps } from '@rocket.chat/apps';\nimport { Message, Team } from '@rocket.chat/core-services';\nimport type { IRoom, IUser, AtLeast } from '@rocket.chat/core-typings';\nimport { Rooms } from '@rocket.chat/models';\nimport { Meteor } from 'meteor/meteor';\n\nimport { hasPermissionAsync } from './authorization/hasPermission';\nimport { deleteRoom } from './rooms/deleteRoom';\nimport { roomCoordinator } from './rooms/roomCoordinator';\n\nexport async function eraseRoom(roomOrId: string | IRoom, user: AtLeast<IUser, '_id' | 'name' | 'username' | 'roles'>): Promise<void> {\n\tconst room = typeof roomOrId === 'string' ? await Rooms.findOneById(roomOrId) : roomOrId;\n\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\tmethod: 'eraseRoom',\n\t\t});\n\t}\n\n\tif (room.federated) {\n\t\tthrow new Meteor.Error('error-cannot-delete-federated-room', 'Cannot delete federated room', {\n\t\t\tmethod: 'eraseRoom',\n\t\t});\n\t}\n\n\tif (\n\t\t!(await roomCoordinator\n\t\t\t.getRoomDirectives(room.t)\n\t\t\t?.canBeDeleted((permissionId, rid) => hasPermissionAsync(user, permissionId, rid), room))\n\t) {\n\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', {\n\t\t\tmethod: 'eraseRoom',\n\t\t});","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/eraseRoom.ts#L1-L33","documentation":"eraseRoom resolves the room (looking it up by id when a string is passed) and throws this Meteor.Error when no room document exists. Deletion of an already-absent room is refused rather than treated as a no-op.","triggerScenarios":"Calling eraseRoom with a room id that was already deleted, an id from another deployment, a typo'd _id, or a falsy room argument.","commonSituations":"Two admins racing to delete the same room; UI acting on a cached room deleted elsewhere; scripts passing stale ids.","solutions":["Re-fetch the room by id and confirm it still exists before issuing the delete","If it was already deleted, treat the outcome as success in the caller (idempotent delete)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const room = typeof roomOrId === 'string' ? await Rooms.findOneById(roomOrId) : roomOrId;\nif (!room) {\n  // room already gone: treat the delete as complete (idempotent) instead of calling eraseRoom\n}","typeGuard":"const isExistingRoom = (room: IRoom | null | undefined): room is IRoom =>\n  Boolean(room && room._id);","tryCatchPattern":null,"preventionTips":["Refresh room state before offering destructive actions","Make delete flows idempotent: a missing room is success, not failure"],"tags":["rooms","deletion","not-found"],"backgroundTag":"room-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}