{"record":{"id":"1ffa7318f498e586","repo":"nopSolutions/nopCommerce","slug":"system-role-could-not-be-deleted","errorCode":null,"errorMessage":"System role could not be deleted","messagePattern":"System role could not be deleted","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Customers/CustomerService.cs","lineNumber":1239,"sourceCode":"\r\n        var mapping = await _customerCustomerRoleMappingRepository.Table\r\n            .SingleOrDefaultAsync(ccrm => ccrm.CustomerId == customer.Id && ccrm.CustomerRoleId == role.Id);\r\n\r\n        if (mapping != null)\r\n            await _customerCustomerRoleMappingRepository.DeleteAsync(mapping);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Delete a customer role\r\n    /// </summary>\r\n    /// <param name=\"customerRole\">Customer role</param>\r\n    /// <returns>A task that represents the asynchronous operation</returns>\r\n    public virtual async Task DeleteCustomerRoleAsync(CustomerRole customerRole)\r\n    {\r\n        ArgumentNullException.ThrowIfNull(customerRole);\r\n\r\n        if (customerRole.IsSystemRole)\r\n            throw new NopException(\"System role could not be deleted\");\r\n\r\n        await _customerRoleRepository.DeleteAsync(customerRole);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Gets a customer role\r\n    /// </summary>\r\n    /// <param name=\"customerRoleId\">Customer role identifier</param>\r\n    /// <returns>\r\n    /// A task that represents the asynchronous operation\r\n    /// The task result contains the customer role\r\n    /// </returns>\r\n    public virtual async Task<CustomerRole> GetCustomerRoleByIdAsync(int customerRoleId)\r\n    {\r\n        var allRolesById = await GetAllCustomerRolesDictionaryAsync();\r\n\r\n        return allRolesById.TryGetValue(customerRoleId, out var role) ? role : null;\r\n    }\r","sourceCodeStart":1221,"sourceCodeEnd":1257,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Customers/CustomerService.cs#L1221-L1257","documentation":"Thrown by DeleteCustomerRoleAsync as a NopException when customerRole.IsSystemRole is true. System roles (Registered, Guests, Administrators, etc.) underpin authorization and cannot be removed; the guard prevents breaking role-based access control.","triggerScenarios":"Calling DeleteCustomerRoleAsync on a role whose IsSystemRole flag is true (the seed/system roles).","commonSituations":"A role-management admin screen that lists all roles without hiding system ones; an automated cleanup that purges 'unused' roles by misclassifying them; a refactor that removed the IsSystemRole UI filter.","solutions":["Exclude system roles from delete actions: filter the list by IsSystemRole == false.","In the role-management UI, hide or disable the delete control for system roles.","If a role must effectively retire, deactivate it (Active=false) rather than delete."],"exampleFix":"// before\nawait _customerService.DeleteCustomerRoleAsync(role);\n\n// after\nif (role.IsSystemRole)\n    return; // or notify: system roles cannot be deleted\nawait _customerService.DeleteCustomerRoleAsync(role);","handlingStrategy":"validation","validationCode":"if (role.IsSystemRole) return; // protected\nawait _customerService.DeleteCustomerRoleAsync(role);","typeGuard":"static bool IsDeletableRole(CustomerRole r) => r is not null && !r.IsSystemRole;","tryCatchPattern":null,"preventionTips":["Hide/disable delete controls for roles where IsSystemRole is true.","Deactivate (Active=false) instead of deleting when a role must retire.","Audit role-management screens to enforce the IsSystemRole filter."],"tags":["customer","role","system-role","delete","security","safety"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}