nopSolutions/nopCommerce · error · ArgumentException

Discount could not be loaded

Error message

Discount could not be loaded

What it means

Thrown by DiscountRulesCustomerRolesController.Configure as an ArgumentException when _discountService.GetDiscountByIdAsync(discountId) returns null — i.e. no discount exists with the supplied id. The action is guarded by DISCOUNTS_VIEW permission.

Source

Thrown at src/Plugins/Nop.Plugin.DiscountRules.CustomerRoles/Controllers/DiscountRulesCustomerRolesController.cs:70

    /// Get errors message from model state
    /// </summary>
    /// <param name="modelState">Model state</param>
    /// <returns>Errors message</returns>
    protected IEnumerable<string> GetErrorsFromModelState(ModelStateDictionary modelState)
    {
        return ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage));
    }

    #endregion

    #region Methods

    [CheckPermission(StandardPermission.Promotions.DISCOUNTS_VIEW)]
    public async Task<IActionResult> Configure(int discountId, int? discountRequirementId)
    {
        //load the discount
        var discount = await _discountService.GetDiscountByIdAsync(discountId)
                       ?? throw new ArgumentException("Discount could not be loaded");

        //check whether the discount requirement exists
        if (discountRequirementId.HasValue && await _discountService.GetDiscountRequirementByIdAsync(discountRequirementId.Value) is null)
            return Content("Failed to load requirement.");

        //try to get previously saved restricted customer role identifier
        var restrictedRoleId = await _settingService.GetSettingByKeyAsync<int>(string.Format(DiscountRequirementDefaults.SettingsKey, discountRequirementId ?? 0));

        var model = new RequirementModel
        {
            RequirementId = discountRequirementId ?? 0,
            DiscountId = discountId,
            CustomerRoleId = restrictedRoleId,
            //set available customer roles
            AvailableCustomerRoles = (await _customerService.GetAllCustomerRolesAsync(true)).Select(role => new SelectListItem
            {
                Text = role.Name,
                Value = role.Id.ToString(),

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Navigate back to the discounts list and open a valid discount.
  2. If linking programmatically, verify the discount id exists before building the URL.
  3. Handle the 500/exception gracefully in the calling UI (show 'discount not found') instead of relying on the raw throw.

Example fix

// before
var discount = await _discountService.GetDiscountByIdAsync(discountId)
               ?? throw new ArgumentException("Discount could not be loaded");
// after (caller-side guard)
var discount = await _discountService.GetDiscountByIdAsync(discountId);
if (discount is null) return NotFound($"Discount {discountId} not found.");
Defensive patterns

Strategy: validation

Validate before calling

var discount = await _discountService.GetDiscountByIdAsync(discountId);
if (discount is null) return NotFound("Discount not found.");
// proceed to Configure logic

Type guard

static bool DiscountExists(IDiscountService svc, int id)
    => svc.GetDiscountByIdAsync(id).GetAwaiter().GetResult() is not null;

Try / catch

try { return await Configure(discountId, reqId); }
catch (ArgumentException ex) when (ex.Message.Contains("Discount could not be loaded"))
{ return NotFound(ex.Message); }

Prevention

When it happens

Trigger: A request to the discount-rules customer-roles configuration endpoint with a discountId that does not exist in the Discount table (deleted, never existed, or wrong id). Commonly hit when the admin UI loads a stale link to a deleted discount.

Common situations: A discount was deleted but a browser tab/bookmark still points at its configuration URL; a malformed or hand-crafted request with an arbitrary id; concurrency where the discount is removed between page load and the configure POST.

Related errors


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