{"record":{"id":"ff65220be34cfb9a","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-ff6522","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/rooms/executeUnbanUserFromRoom.ts","lineNumber":11,"sourceCode":"import { Message } from '@rocket.chat/core-services';\nimport { isBannedSubscription, isInviteSubscription, type IUser } from '@rocket.chat/core-typings';\nimport { Rooms, Subscriptions, Users } from '@rocket.chat/models';\n\nimport { afterUnbanFromRoomCallback } from '../callbacks/afterUnbanFromRoomCallback';\nimport { notifyOnRoomChangedById, notifyOnSubscriptionChanged } from '../notifyListener';\n\nexport const executeUnbanUserFromRoom = async function (rid: string, user: IUser, byUser: IUser): Promise<void> {\n\tconst room = await Rooms.findOneById(rid);\n\tif (!room) {\n\t\tthrow new Error('error-invalid-room');\n\t}\n\n\tif (!user.username) {\n\t\tthrow new Error('error-invalid-user');\n\t}\n\n\tconst subscription = await Subscriptions.findOneByRoomIdAndUserId(rid, user._id);\n\tif (!subscription) {\n\t\tthrow new Error('error-invalid-subscription');\n\t}\n\n\t// if the subscription is an invite it means we were unbanned and then invited again, then\n\t// the invite was accepted and we receive a leave event (meaning the user was unbanned), so\n\t// at this point we just need send the message to say the user was unbanned.\n\tif (isInviteSubscription(subscription)) {\n\t\tawait Message.saveSystemMessage('user-unbanned', rid, user.username, user, {\n\t\t\tu: { _id: byUser._id, username: byUser.username },\n\t\t});","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/rooms/executeUnbanUserFromRoom.ts#L1-L29","documentation":"executeUnbanUserFromRoom resolves the room by id with Rooms.findOneById(rid); if no room document matches, it throws the plain Error 'error-invalid-room'. Callers (e.g. the unbanUserFromRoom method or federation events) propagate this to the client.","triggerScenarios":"Calling executeUnbanUserFromRoom with a rid that does not exist in the Rooms collection — deleted room, typo'd/truncated id, stale rid from an old UI session or federation event referencing a room purged after the ban was created.","commonSituations":"Unbanning from a message action clicked in a long-open browser session after the room was deleted; federation or app events replayed with stale room ids; scripts operating on exported room ids after a partial restore.","solutions":["Verify the rid exists with Rooms.findOneById before calling the unban flow","If the room was deleted, discard the stale ban entry or event instead of unbanning","Validate federation/app event rids against current Rooms and drop orphans"],"exampleFix":"// before\nawait executeUnbanUserFromRoom(ridFromEvent, user, byUser);\n\n// after\nif (!(await Rooms.findOneById(rid, { projection: { _id: 1 } }))) {\n  throw new Meteor.Error('error-invalid-room', `Room ${rid} not found`);\n}\nawait executeUnbanUserFromRoom(ridFromEvent, user, byUser);","handlingStrategy":"validation","validationCode":"const room = await Rooms.findOneById(rid, { projections: { _id: 1 } });\nif (!room) {\n  throw new Meteor.Error('error-invalid-room', `Room ${rid} not found`);\n}\nawait executeUnbanUserFromRoom(rid, user, byUser);","typeGuard":null,"tryCatchPattern":"try {\n  await executeUnbanUserFromRoom(rid, user, byUser);\n} catch (err) {\n  if (err instanceof Error && err.message === 'error-invalid-room') {\n    // room gone — drop the stale ban record in the UI, nothing to unban\n  }\n  throw err;\n}","preventionTips":["Refresh room existence before showing moderation actions","Purge queued federation/app events referencing deleted rooms","Use server-side rid values from subscriptions, not client-cached ones"],"tags":["room","unban","validation","room-not-found"],"backgroundTag":"room-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}