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

  1. Use a unique DisplayName per tenant or resolve duplicates by changing one display name
  2. Catch UserFriendlyException and surface the localized message in the form
  3. Pass the role's own Id as expectedRoleId on update so self-matches pass
  4. 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

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


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)