{"record":{"id":"baffed96af7adcd1","repo":"RocketChat/Rocket.Chat","slug":"error-action-not-allowed-baffed","errorCode":"error-action-not-allowed","errorMessage":"Leaving the app without an active admin is not allowed","messagePattern":"Leaving the app without an active admin is not allowed","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/users/setUserActiveStatus.ts","lineNumber":78,"sourceCode":"\n\tconst user = await Users.findOneById(userId);\n\n\tif (!user) {\n\t\treturn false;\n\t}\n\n\tif (isUserFederated(user)) {\n\t\tthrow new Meteor.Error('error-user-is-federated', 'Cannot change federated users status', {\n\t\t\tmethod: 'setUserActiveStatus',\n\t\t});\n\t}\n\n\t// Users without username can't do anything, so there is no need to check for owned rooms\n\tif (user.username != null && !active) {\n\t\tconst userAdmin = await Users.findOneAdmin(userId || '');\n\t\tconst adminsCount = await Users.countActiveUsersInRoles(['admin']);\n\t\tif (userAdmin && adminsCount === 1) {\n\t\t\tthrow new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', {\n\t\t\t\tmethod: 'removeUserFromRole',\n\t\t\t\taction: 'Remove_last_admin',\n\t\t\t});\n\t\t}\n\n\t\tconst subscribedRooms = await getSubscribedRoomsForUserWithDetails(userId);\n\t\t// give omnichannel rooms a special treatment :)\n\t\tconst chatSubscribedRooms = subscribedRooms.filter(({ t }) => t !== 'l');\n\t\tconst livechatSubscribedRooms = subscribedRooms.filter(({ t }) => t === 'l');\n\n\t\tif (shouldRemoveOrChangeOwner(chatSubscribedRooms) && !confirmRelinquish) {\n\t\t\tconst rooms = await getUserSingleOwnedRooms(chatSubscribedRooms as []);\n\t\t\tthrow new Meteor.Error('user-last-owner', '', rooms);\n\t\t}\n\n\t\t// We don't want one killing the other :)\n\t\tawait Promise.allSettled([\n\t\t\tcloseOmnichannelConversations(user, livechatSubscribedRooms, executedBy),","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/users/setUserActiveStatus.ts#L60-L96","documentation":"setUserActiveStatus throws error-action-not-allowed when deactivating (active=false) the last remaining active admin: it checks the target is an admin (findOneAdmin) and that the count of active users in the admin role is exactly 1. This is a deliberate guard to prevent locking the workspace out of administration.","triggerScenarios":"Deactivating the sole active admin account — typically via the admin UI's deactivate action or the REST users.deactivate endpoint; also hit by scripts that deactivate users in bulk including every admin.","commonSituations":"Offboarding the founding admin without naming a successor; test/demo workspaces with a single admin account; automated deactivation scripts not excluding admins.","solutions":["Promote another (active) user to the admin role first, then retry the deactivation.","Or reactivate an existing inactive admin before disabling the current one.","Adjust bulk scripts to skip admins or verify at least one other active admin remains before each deactivation."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const user = await Users.findOneAdmin(userId);\nif (user) {\n  const activeAdmins = await Users.countActiveUsersInRoles(['admin']);\n  if (activeAdmins <= 1) {\n    throw new Meteor.Error('error-last-admin', 'Promote another active admin before deactivating this user');\n  }\n}\nawait setUserActiveStatus(userId, false, confirmRelinquish);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Before offboarding any admin, verify at least one other active admin exists.","Bulk deactivation scripts must skip users in the admin role unless a successor is confirmed.","Keep a break-glass admin account active on production workspaces."],"tags":["admin","user-management","permissions","safety-guard"],"backgroundTag":"last-admin-protection","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}