nopSolutions/nopCommerce · warning · NopException

You cannot specify "Purchased with product" value for "Regis

Error message

You cannot specify "Purchased with product" value for "Registered" customer role

What it means

Thrown in the CustomerRole Edit action when the role's SystemName equals NopCustomerDefaults.RegisteredRoleName (the built-in 'Registered' role) and the model.PurchasedWithProductId is greater than zero. The Registered role is assigned automatically upon customer registration; binding it to a product purchase would conflict with that auto-assignment logic. NopException, caught and shown as an error notification.

Source

Thrown at src/Presentation/Nop.Web/Areas/Admin/Controllers/CustomerRoleController.cs:155

    {
        //try to get a customer role with the specified id
        var customerRole = await _customerService.GetCustomerRoleByIdAsync(model.Id);
        if (customerRole == null)
            return RedirectToAction("List");

        try
        {
            if (ModelState.IsValid)
            {
                if (customerRole.IsSystemRole && !model.Active)
                    throw new NopException(await _localizationService.GetResourceAsync("Admin.Customers.CustomerRoles.Fields.Active.CantEditSystem"));

                if (customerRole.IsSystemRole && !customerRole.SystemName.Equals(model.SystemName, StringComparison.InvariantCultureIgnoreCase))
                    throw new NopException(await _localizationService.GetResourceAsync("Admin.Customers.CustomerRoles.Fields.SystemName.CantEditSystem"));

                if (NopCustomerDefaults.RegisteredRoleName.Equals(customerRole.SystemName, StringComparison.InvariantCultureIgnoreCase) &&
                    model.PurchasedWithProductId > 0)
                    throw new NopException(await _localizationService.GetResourceAsync("Admin.Customers.CustomerRoles.Fields.PurchasedWithProduct.Registered"));

                customerRole = model.ToEntity(customerRole);
                await _customerService.UpdateCustomerRoleAsync(customerRole);

                //activity log
                await _customerActivityService.InsertActivityAsync("EditCustomerRole",
                    string.Format(await _localizationService.GetResourceAsync("ActivityLog.EditCustomerRole"), customerRole.Name), customerRole);

                _notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.CustomerRoles.Updated"));

                return continueEditing ? RedirectToAction("Edit", new { id = customerRole.Id }) : RedirectToAction("List");
            }

            //prepare model
            model = await _customerRoleModelFactory.PrepareCustomerRoleModelAsync(model, customerRole, true);

            //if we got this far, something failed, redisplay form
            return View(model);

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Create a dedicated non-system customer role (e.g. 'Premium Member') and set PurchasedWithProduct on that role instead.
  2. Clear the PurchasedWithProductId field (set to 0/none) when editing the Registered role.
  3. Audit any role-seeding scripts to only assign PurchasedWithProduct to non-Registered roles.

Example fix

// before — Registered role submitted with PurchasedWithProductId > 0 -> NopException

// after — assign the purchased-with-product linkage to a custom role
var premiumRole = await _customerService.GetCustomerRoleBySystemNameAsync("PremiumMember");
premiumRole.PurchasedWithProductId = productId;
await _customerService.UpdateCustomerRoleAsync(premiumRole);
Defensive patterns

Strategy: validation

Validate before calling

// Before saving: the Registered role must not carry a purchased-with product
var role = await _customerService.GetCustomerRoleByIdAsync(model.Id);
if (NopCustomerDefaults.RegisteredRoleName.Equals(role?.SystemName, StringComparison.OrdinalIgnoreCase) && model.PurchasedWithProductId > 0)
{
    ModelState.AddModelError("PurchasedWithProductId", "Cannot set PurchasedWithProduct on the Registered role.");
    return View(model);
}

Type guard

bool CanSetPurchasedWithProduct(CustomerRole role) => !NopCustomerDefaults.RegisteredRoleName.Equals(role?.SystemName, StringComparison.OrdinalIgnoreCase);

Try / catch

// The Edit action's try/catch shows the localized notification; use a custom non-system role instead.

Prevention

When it happens

Trigger: POST to CustomerRole/Edit for the Registered system role with a PurchasedWithProductId > 0 (a product selected in the 'Purchased with product' picker).

Common situations: An admin tries to set up a 'buy X to become a member' flow and mistakenly targets the default Registered role instead of a custom role; a configuration tool applies purchased-with-product settings to all roles indiscriminately.

Related errors


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