nopSolutions/nopCommerce · warning · NopException

Account.EmailUsernameErrors.UsernameAlreadyExists

Error message

Account.EmailUsernameErrors.UsernameAlreadyExists

What it means

Thrown by SetUsernameAsync when GetCustomerByUsernameAsync(newUsername) returns a different customer, using localized resource 'Account.EmailUsernameErrors.UsernameAlreadyExists'. Enforces username uniqueness.

Source

Thrown at src/Libraries/Nop.Services/Customers/CustomerRegistrationService.cs:577

    /// </summary>
    /// <param name="customer">Customer</param>
    /// <param name="newUsername">New Username</param>
    /// <returns>A task that represents the asynchronous operation</returns>
    public virtual async Task SetUsernameAsync(Customer customer, string newUsername)
    {
        ArgumentNullException.ThrowIfNull(customer);

        if (!_customerSettings.UsernamesEnabled)
            throw new NopException("Usernames are disabled");

        newUsername = newUsername.Trim();

        if (newUsername.Length > NopCustomerServicesDefaults.CustomerUsernameLength)
            throw new NopException(await _localizationService.GetResourceAsync("Account.EmailUsernameErrors.UsernameTooLong"));

        var user2 = await _customerService.GetCustomerByUsernameAsync(newUsername);
        if (user2 != null && customer.Id != user2.Id)
            throw new NopException(await _localizationService.GetResourceAsync("Account.EmailUsernameErrors.UsernameAlreadyExists"));

        customer.Username = newUsername;
        await _customerService.UpdateCustomerAsync(customer);
    }

    #endregion
}

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Pre-check uniqueness with GetCustomerByUsernameAsync before calling SetUsernameAsync.
  2. Suggest available alternatives when a collision is detected.
  3. Surface the localized message to the user as a validation error.

Example fix

// before
await _customerRegistrationService.SetUsernameAsync(customer, newUsername);

// after
var owner = await _customerService.GetCustomerByUsernameAsync(newUsername);
if (owner is not null && owner.Id != customer.Id)
    ModelState.AddModelError(nameof(newUsername), "This username is already taken.");
else
    await _customerRegistrationService.SetUsernameAsync(customer, newUsername);
Defensive patterns

Strategy: validation

Validate before calling

var owner = await _customerService.GetCustomerByUsernameAsync(newUsername);
if (owner is not null && owner.Id != customer.Id)
    ModelState.AddModelError(nameof(newUsername), "Username already taken.");

Try / catch

try { await _customerRegistrationService.SetUsernameAsync(customer, username); }
catch (NopException ex) { ModelState.AddModelError(nameof(username), ex.Message); }

Prevention

When it happens

Trigger: Calling SetUsernameAsync with a username already taken by another customer account.

Common situations: User picks a popular handle; admin reassigns a taken username; duplicate-account merge.

Related errors


AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13). Data as JSON: /api/errors/aaab5340e5806011. Report an issue: GitHub.