aspnetboilerplate/aspnetboilerplate · error · UserFriendlyException
RoleDisplayNameIsAlreadyTaken
Error message
RoleDisplayNameIsAlreadyTaken
What it means
AbpRoleManager.CheckDuplicateRoleNameAsync also enforces uniqueness of the role's DisplayName. It throws UserFriendlyException 'RoleDisplayNameIsAlreadyTaken' when FindByDisplayNameAsync(displayName) returns a role with a different Id than expectedRoleId.
Solutions
- Use a unique DisplayName per tenant or resolve duplicates by changing one display name
- Catch UserFriendlyException and surface the localized message in the form
- Pass the role's own Id as expectedRoleId on update so self-matches pass
- Consider whether your app really needs display-name uniqueness; if not, override CheckDuplicateRoleNameAsync
Example fix
// before
await _roleManager.CheckDuplicateRoleNameAsync(null, "manager", "Manager"); // display name taken
// after
var clash = await _roleManager.FindByDisplayNameAsync("Manager");
if (clash == null) await _roleManager.CreateAsync(new TRole { Name = "manager", DisplayName = "Manager" }); Defensive patterns
Strategy: validation
Validate before calling
var existing = await _roleManager.FindByDisplayNameAsync(displayName);
if (existing != null && existing.Id != expectedRoleId)
throw new UserFriendlyException(string.Format(L("RoleDisplayNameIsAlreadyTaken"), displayName)); Try / catch
try { await _roleManager.CheckDuplicateRoleNameAsync(expectedRoleId, name, displayName); }
catch (UserFriendlyException ex) { ModelState.AddModelError("DisplayName", ex.Message); return BadRequest(ModelState); } Prevention
- Check both name and display name before role create/update
- Trim/normalize display names; avoid invisible whitespace duplicates
- Decide intentionally whether display-name uniqueness matters for your tenant
- Catch UserFriendlyException in your app service instead of letting it bubble raw
When it happens
Trigger: Creating a role whose DisplayName matches another role's, or updating a role's DisplayName to one owned by a different role.
Common situations: Multi-language UI where two roles share a display label; admin creating 'Manager' display name twice; upgrade scenarios where seeding added a role with the same display name as a user-created one.
Related errors
- RoleNameIsAlreadyTaken
- OrganizationUnitDuplicateDisplayNameWarning
- CanNotDeleteStaticRole
- Identity.DuplicateEmail
- Identity.DuplicateUserName
AI-assisted analysis of aspnetboilerplate/aspnetboilerplate@2323c13a15 (2026-09-08).
Data as JSON: /api/errors/0ca9d2a944786356.
Report an issue: GitHub.
Appendix: source
Thrown at src/Abp.ZeroCore/Authorization/Roles/AbpRoleManager.cs:438
return IdentityResult.Success;
});
}
public virtual async Task<IdentityResult> CheckDuplicateRoleNameAsync(
int? expectedRoleId,
string name,
string displayName)
{
var role = await FindByNameAsync(name);
if (role != null && role.Id != expectedRoleId)
{
throw new UserFriendlyException(string.Format(L("RoleNameIsAlreadyTaken"), name));
}
role = await FindByDisplayNameAsync(displayName);
if (role != null && role.Id != expectedRoleId)
{
throw new UserFriendlyException(string.Format(L("RoleDisplayNameIsAlreadyTaken"), displayName));
}
return IdentityResult.Success;
}
/// <summary>
/// Gets roles of a given organizationUnit
/// </summary>
/// <param name="organizationUnit">OrganizationUnit to get belonging roles </param>
/// <param name="includeChildren">Includes roles for children organization units to result when true. Default is false</param>
/// <returns></returns>
public virtual async Task<List<TRole>> GetRolesInOrganizationUnitAsync(
OrganizationUnit organizationUnit,
bool includeChildren = false)
{
return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
{
if (!includeChildren)View on GitHub (pinned to 2323c13a15)