nopSolutions/nopCommerce · error · NopException

Email cannot be null

Error message

Email cannot be null

What it means

Thrown by SetEmailAsync as a NopException when the newEmail argument is exactly null. This is a defensive check after the explicit ArgumentNullException.ThrowIfNull(customer) guard; it distinguishes a null email (programmer error) from an invalid one (user error).

Source

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

        if (!string.IsNullOrEmpty(returnUrl) && _webHelper.CheckIsLocalUrl(returnUrl))
            return new RedirectResult(returnUrl);

        return new RedirectToRouteResult(NopRouteNames.General.HOMEPAGE, null);
    }

    /// <summary>
    /// Sets a user email
    /// </summary>
    /// <param name="customer">Customer</param>
    /// <param name="newEmail">New email</param>
    /// <param name="requireValidation">Require validation of new email address</param>
    /// <returns>A task that represents the asynchronous operation</returns>
    public virtual async Task SetEmailAsync(Customer customer, string newEmail, bool requireValidation)
    {
        ArgumentNullException.ThrowIfNull(customer);

        if (newEmail == null)
            throw new NopException("Email cannot be null");

        newEmail = newEmail.Trim();
        var oldEmail = customer.Email;

        if (!CommonHelper.IsValidEmail(newEmail))
            throw new NopException(await _localizationService.GetResourceAsync("Account.EmailUsernameErrors.NewEmailIsNotValid"));

        if (newEmail.Length > 100)
            throw new NopException(await _localizationService.GetResourceAsync("Account.EmailUsernameErrors.EmailTooLong"));

        var customer2 = await _customerService.GetCustomerByEmailAsync(newEmail);
        if (customer2 != null && customer.Id != customer2.Id)
            throw new NopException(await _localizationService.GetResourceAsync("Account.EmailUsernameErrors.EmailAlreadyExists"));

        if (requireValidation)
        {
            //re-validate email
            customer.EmailToRevalidate = newEmail;

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Ensure the caller never passes null: coalesce to empty or validate presence before calling SetEmailAsync.
  2. Make the source field non-nullable and required at the API boundary (e.g., [Required] on the request model).
  3. If null is legitimately possible, short-circuit: if (newEmail is null) return; or surface a proper validation message.

Example fix

// before
await _customerRegistrationService.SetEmailAsync(customer, model.Email, requireValidation: true);

// after
if (model.Email is null)
    ModelState.AddModelError(nameof(model.Email), "Email is required.");
else
    await _customerRegistrationService.SetEmailAsync(customer, model.Email, requireValidation: true);
Defensive patterns

Strategy: validation

Validate before calling

if (newEmail is null)
    throw new InvalidOperationException("newEmail must not be null at this point.");
await _customerRegistrationService.SetEmailAsync(customer, newEmail, requireValidation);

Type guard

static bool IsEmailProvided(string email) => email is not null;

Prevention

When it happens

Trigger: Calling await customerRegistrationService.SetEmailAsync(customer, null, requireValidation) — passing a literal null or a variable that was never assigned. Distinct from an empty/invalid string which hits a different branch.

Common situations: A controller action binding a nullable email field from a form/query and forwarding it without null-coalescing; deserialization of a customer-import payload where the email node was omitted; a refactor that changed the caller to read from an optional setting.

Related errors


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