{"record":{"id":"8454985b0ec9460c","repo":"RocketChat/Rocket.Chat","slug":"error-role-protected-845498","errorCode":"error-role-protected","errorMessage":"Cannot delete a protected role","messagePattern":"Cannot delete a protected role","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"warning","filePath":"apps/meteor/server/api/v1/roles.ts","lineNumber":243,"sourceCode":"\t\t\t\t\trequired: ['success'],\n\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t}),\n\t\t\t\t400: validateBadRequestErrorResponse,\n\t\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t\t403: validateForbiddenErrorResponse,\n\t\t\t},\n\t\t},\n\t\tasync function action() {\n\t\t\tconst { bodyParams } = this;\n\n\t\t\tconst role = await Roles.findOneByIdOrName(bodyParams.roleId);\n\n\t\t\tif (!role) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-roleId', 'This role does not exist');\n\t\t\t}\n\n\t\t\tif (role.protected) {\n\t\t\t\tthrow new Meteor.Error('error-role-protected', 'Cannot delete a protected role');\n\t\t\t}\n\n\t\t\tif ((await Roles.countUsersInRole(role._id)) > 0) {\n\t\t\t\tthrow new Meteor.Error('error-role-in-use', \"Cannot delete role because it's in use\");\n\t\t\t}\n\n\t\t\tawait Roles.removeById(role._id);\n\n\t\t\tvoid notifyOnRoleChanged(role, 'removed');\n\n\t\t\treturn API.v1.success();\n\t\t},\n\t)\n\t.post(\n\t\t'roles.removeUserFromRole',\n\t\t{\n\t\t\tauthRequired: true,\n\t\t\tpermissionsRequired: ['access-permissions'],","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/roles.ts#L225-L261","documentation":"Thrown by POST roles.delete when the resolved role has role.protected === true. Protected roles (e.g. admin, owner, moderator, user) are built-in and cannot be removed. Returns a structured Meteor.Error('error-role-protected', 'Cannot delete a protected role').","triggerScenarios":"POST /api/v1/roles.delete targeting a built-in protected role whose documents has protected:true.","commonSituations":"Admin UI/script attempts to remove a system role to simplify permissions; migration tries to drop the 'admin' or 'user' role.","solutions":["Do not delete protected roles; instead remove users from the role or adjust permissions if you need to change behavior.","Filter the role list by protected===false before offering a delete action in the UI.","Create a custom non-protected role if you need a deletable equivalent."],"exampleFix":"// before\nawait fetch('/api/v1/roles.delete', { method:'POST', body: JSON.stringify({ roleId }) });\n\n// after - block protected roles in the UI\nconst role = roles.find(r => r._id === roleId);\nif (role?.protected) {\n  alert('Protected roles cannot be deleted');\n  return;\n}\nawait fetch('/api/v1/roles.delete', { method:'POST', body: JSON.stringify({ roleId }) });","handlingStrategy":"type-guard","validationCode":"const role = roles.find(r => r._id === roleId);\nif (!role || role.protected) {\n  throw new Error('Protected or unknown roles cannot be deleted');\n}\nawait fetch('/api/v1/roles.delete', { method:'POST', body: JSON.stringify({ roleId }) });","typeGuard":"function isDeletableRole(role: { protected?: boolean } | undefined): role is { protected: false } {\n  return !!role && role.protected !== true;\n}","tryCatchPattern":null,"preventionTips":["Filter protected roles out of the deletable list in the UI.","Never script deletion of built-in system roles."],"tags":["roles","rest-api","protected","delete","business-rule"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}