{"record":{"id":"301c02490ebcb141","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-301c02","errorCode":"error-invalid-room","errorMessage":"Invalid room","messagePattern":"Invalid room","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/rooms/removeRoomModerator.ts","lineNumber":29,"sourceCode":"import { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';\nimport { notifyOnSubscriptionChangedById } from '../../lib/notifyListener';\nimport { syncRoomRolePriorityForUserAndRoom } from '../../lib/roles/syncRoomRolePriority';\nimport { settings } from '../../settings';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tremoveRoomModerator(rid: IRoom['_id'], userId: IUser['_id']): boolean;\n\t}\n}\n\nexport const removeRoomModerator = async (fromUserId: IUser['_id'], rid: IRoom['_id'], userId: IUser['_id']): Promise<boolean> => {\n\tcheck(rid, String);\n\tcheck(userId, String);\n\n\tconst room = await Rooms.findOneById(rid, { projection: { t: 1, federated: 1, federation: 1 } });\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\tmethod: 'removeRoomModerator',\n\t\t});\n\t}\n\n\tif (!(await hasPermissionAsync(fromUserId, 'set-moderator', rid)) && !isRoomFederated(room)) {\n\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', {\n\t\t\tmethod: 'removeRoomModerator',\n\t\t});\n\t}\n\n\tconst user = await Users.findOneById(userId);\n\n\tif (!user?.username) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', {\n\t\t\tmethod: 'removeRoomModerator',\n\t\t});\n\t}\n","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/removeRoomModerator.ts#L11-L47","documentation":"removeRoomModerator starts by loading the room with Rooms.findOneById(rid, ...) and throws error-invalid-room when no document matches. This fires before permission and user checks, so any nonexistent, deleted, or malformed room ID produces it. The second argument must be the room's _id, not its name.","triggerScenarios":"Passing a channel name or slug instead of the room _id; the room was deleted between the UI loading it and the method executing; a truncated or typo'd ObjectId string.","commonSituations":"Stale UI referencing a channel deleted by another admin; data copied between environments where room IDs differ; federation or app sync removing the room mid-flow.","solutions":["Resolve the room first (client Rooms collection or GET /api/v1/rooms.info?roomId=) and pass the returned _id","Refresh the room list in the client when the call fails to clear stale IDs","Never build rid from a name; look up the _id explicitly"],"exampleFix":"// before\nawait Meteor.callAsync('removeRoomModerator', roomName, userId);\n\n// after\nconst room = Rooms.findOne({ name: roomName });\nif (!room) throw new Error('room gone');\nawait Meteor.callAsync('removeRoomModerator', room._id, userId);","handlingStrategy":"validation","validationCode":"const room = Rooms.findOne({ _id: rid });\nif (!room) {\n  // refetch room list; the rid is stale or wrong\n}","typeGuard":"const isExistingRoom = (rid: string | undefined): rid is string =>\n  typeof rid === 'string' && rid.length > 0 && Rooms.findOne({ _id: rid }) != null;","tryCatchPattern":"try {\n  await Meteor.callAsync('removeRoomModerator', rid, userId);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'error-invalid-room') {\n    // room gone: refresh UI state, do not retry the same rid\n  }\n}","preventionTips":["Always pass the room _id resolved from a lookup, never a name","Refetch room lists after delete/leave events","Validate rid shape before calling"],"tags":["rooms","meteor-methods","validation"],"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-23T08:17:48.524Z"}