nopSolutions/nopCommerce · error · ArgumentException

No filter level value mapping found with the specified id

Error message

No filter level value mapping found with the specified id

What it means

Thrown by the FilterLevelValueDelete action when no mapping in existingProductFilterLevelValues matches the given (productId, id) pair — i.e. FirstOrDefault(...) returns null and the ?? throw new ArgumentException fires. Unlike the other lookups, this first fetches all mappings for the filter-level-value id, then filters client-side by productId. The uncaught ArgumentException propagates as an HTTP 500 to the grid delete request.

Source

Thrown at src/Presentation/Nop.Web/Areas/Admin/Controllers/ProductController.cs:1920

        var currentVendor = await _workContext.GetCurrentVendorAsync();
        if (currentVendor != null && product.VendorId != currentVendor.Id)
            return Content("This is not your product");

        //prepare model
        var model = await _productModelFactory.PrepareFilterLevelValueListModelAsync(searchModel, product);

        return Json(model);
    }

    [HttpPost]
    [CheckPermission(StandardPermission.Catalog.FILTER_LEVEL_VALUE_CREATE_EDIT_DELETE)]
    public virtual async Task<IActionResult> FilterLevelValueDelete(int productId, int id)
    {
        //try to get a filter level value mapping with the specified id
        var existingProductFilterLevelValues = await _filterLevelValueService.GetFilterLevelValueProductsByFilterLevelValueIdAsync(id);

        var filterLevelValueMapping = existingProductFilterLevelValues.FirstOrDefault(pc => pc.ProductId == productId && pc.FilterLevelValueId == id)
            ?? throw new ArgumentException("No filter level value mapping found with the specified id");

        //a vendor should have access only to his products
        var currentVendor = await _workContext.GetCurrentVendorAsync();
        if (currentVendor != null)
        {
            var product = await _productService.GetProductByIdAsync(filterLevelValueMapping.ProductId);
            if (product != null && product.VendorId != currentVendor.Id)
                return Content("This is not your product");
        }

        await _filterLevelValueService.DeleteFilterLevelValueProductAsync(filterLevelValueMapping);

        return new NullJsonResult();
    }

    [CheckPermission(StandardPermission.Catalog.FILTER_LEVEL_VALUE_CREATE_EDIT_DELETE)]
    public virtual async Task<IActionResult> FilterLevelValuesAddPopup(int productId)
    {

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Reload the grid — the mapping is already gone; treat the operation as a no-op success.
  2. Make delete idempotent by returning NullJsonResult when no mapping matches.
  3. Verify both productId and id are valid and paired before submitting.
  4. Disable the delete control client-side after the first click.

Example fix

// before
var filterLevelValueMapping = existingProductFilterLevelValues
    .FirstOrDefault(pc => pc.ProductId == productId && pc.FilterLevelValueId == id)
    ?? throw new ArgumentException("No filter level value mapping found with the specified id");

// after — idempotent delete
var filterLevelValueMapping = existingProductFilterLevelValues
    .FirstOrDefault(pc => pc.ProductId == productId && pc.FilterLevelValueId == id);
if (filterLevelValueMapping == null)
    return new NullJsonResult();
Defensive patterns

Strategy: validation

Validate before calling

// Idempotent delete: tolerate missing (productId, id) pairings
var mappings = await _filterLevelValueService.GetFilterLevelValueProductsByFilterLevelValueIdAsync(id);
var mapping = mappings.FirstOrDefault(pc => pc.ProductId == productId && pc.FilterLevelValueId == id);
if (mapping == null)
    return new NullJsonResult(); // already deleted / not paired

Type guard

if (productId <= 0 || id <= 0) return BadRequest("Invalid ids");

Try / catch

try { var m = existingProductFilterLevelValues.FirstOrDefault(pc => pc.ProductId == productId && pc.FilterLevelValueId == id); if (m == null) return new NullJsonResult(); ... } catch (ArgumentException) { return new NullJsonResult(); }

Prevention

When it happens

Trigger: POST to delete a filter-level-value/product mapping where the combination of productId and id does not exist — the mapping was already deleted, productId and id don't pair, or the grid row is stale.

Common situations: Concurrent deletes of the same mapping; a grid row stale after prior deletion; programmatic delete passing mismatched productId and id; double-submit on delete.

Related errors


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