{"record":{"id":"8ddc149a33d155a4","repo":"RocketChat/Rocket.Chat","slug":"error-user-is-banned-8ddc14","errorCode":"error-user-is-banned","errorMessage":"User is banned from this room","messagePattern":"User is banned from this room","errorType":"error_code","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts","lineNumber":101,"sourceCode":"\t\t});\n\t}\n\n\tawait beforeAddUsersToRoom.run({ usernames: data.users, inviter: user }, room);\n\n\tawait Promise.all(\n\t\tdata.users.map(async (username) => {\n\t\t\tconst sanitizedUsername = sanitizeUsername(username);\n\n\t\t\tconst newUser = await Users.findOneByUsernameIgnoringCase(sanitizedUsername);\n\t\t\tif (!newUser) {\n\t\t\t\tthrow new Meteor.Error('error-user-not-found', 'User not found', {\n\t\t\t\t\tmethod: 'addUsersToRoom',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst subscription = await Subscriptions.findOneByRoomIdAndUserId(data.rid, newUser._id);\n\t\t\tif (subscription && isBannedSubscription(subscription)) {\n\t\t\t\tthrow new Meteor.Error('error-user-is-banned', 'User is banned from this room', {\n\t\t\t\t\tmethod: 'addUsersToRoom',\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (!subscription) {\n\t\t\t\treturn addUserToRoom(data.rid, newUser, user);\n\t\t\t}\n\t\t\tif (!newUser.username) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvoid api.broadcast('notify.ephemeralMessage', userId, data.rid, {\n\t\t\t\tmsg: i18n.t('Username_is_already_in_here', {\n\t\t\t\t\tusername: newUser.username,\n\t\t\t\t\tlng: user?.language,\n\t\t\t\t}),\n\t\t\t});\n\t\t}),\n\t);\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts#L83-L119","documentation":"Thrown inside the per-user loop of addUsersToRoomMethod() (apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts:101) when the target user already has a subscription for the room and isBannedSubscription(subscription) reports them as banned (subscription flagged with 'banned' role/marker from the ban flow, e.g. banUserFromRoom). Re-inviting a banned user is blocked; an unban must happen first. Like error-user-not-found, this rejects the entire Promise.all batch.","triggerScenarios":"Inviting a user who was banned from that channel via /ban or the moderation UI; their old subscription still exists carrying the banned flag; a bulk invite list containing previously banned members; banned user re-joining via invite link paths that route through this method.","commonSituations":"Moderation workflows where bans persist and an admin later tries to re-invite without unbanning; sync scripts replaying full member lists into rooms with bans; confusion between being banned (subscription flag) and having left (no subscription).","solutions":["Unban first: use the moderation flow (unban command or the unban endpoint), then invite again.","Pre-check each target: const sub = await Subscriptions.findOneByRoomIdAndUserId(rid, userId); skip when isBannedSubscription(sub) and report them separately.","Keep bulk jobs resilient: partition targets into 'invitable' vs 'banned' before calling so one banned user cannot reject the batch.","Review whether the ban is still intended; if it is stale moderation data, unban to clear the flag."],"exampleFix":"// before\nawait addUsersToRoomMethod(uid, { rid, users: ['alice', 'banned-bob'] }); // batch rejected\n\n// after\nconst invitable: string[] = [];\nfor (const name of users) {\n  const u = await Users.findOneByUsernameIgnoringCase(sanitizeUsername(name), { projection: { _id: 1 } });\n  const sub = u && (await Subscriptions.findOneByRoomIdAndUserId(rid, u._id, { projection: { roles: 1 } }));\n  if (sub && isBannedSubscription(sub)) continue; // or: await unbanUserFromRoom(rid, u._id);\n  invitable.push(name);\n}\nawait addUsersToRoomMethod(uid, { rid, users: invitable });","handlingStrategy":"validation","validationCode":"const sub = await Subscriptions.findOneByRoomIdAndUserId(rid, targetUserId, { projection: { roles: 1 } });\nif (sub && isBannedSubscription(sub)) {\n  // unban first or exclude from the batch\n  throw new Error('target is banned from this room; unban before inviting');\n}","typeGuard":"import { isBannedSubscription } from '@rocket.chat/core-typings';\n// isBannedSubscription(subscription) is the canonical type guard for this state","tryCatchPattern":"try {\n  await addUsersToRoomMethod(uid, { rid, users });\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-user-is-banned') {\n    // unban the user via the moderation flow, then retry the invite\n  }\n}","preventionTips":["Pre-filter bulk invite lists against subscriptions flagged as banned.\nUnban before re-inviting; never try to bypass the ban by direct DB writes.\nKeep moderation state visible to admins so stale bans get cleaned up."],"tags":["meteor-method","moderation","banned","subscriptions","rooms"],"backgroundTag":"user-banned-from-room","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}