nopSolutions/nopCommerce · error · ArgumentException

No associated product found with the specified id

Error message

No associated product found with the specified id

What it means

Thrown by AssociatedProductUpdate when _productService.GetProductByIdAsync(model.Id) returns null. It is an unhandled ArgumentException surfaced as an HTTP 500 from an admin AJAX endpoint. The endpoint updates the DisplayOrder of a child product under a grouped product. The lookup uses the model.Id posted from the associated-products Kendo grid row.

Source

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

        //a vendor should have access only to his products
        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.PrepareAssociatedProductListModelAsync(searchModel, product);

        return Json(model);
    }

    [HttpPost]
    [CheckPermission(StandardPermission.Catalog.PRODUCTS_CREATE_EDIT_DELETE)]
    public virtual async Task<IActionResult> AssociatedProductUpdate(AssociatedProductModel model)
    {
        //try to get an associated product with the specified id
        var associatedProduct = await _productService.GetProductByIdAsync(model.Id)
            ?? throw new ArgumentException("No associated product found with the specified id");

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

        associatedProduct.DisplayOrder = model.DisplayOrder;
        await _productService.UpdateProductAsync(associatedProduct);

        return new NullJsonResult();
    }

    [HttpPost]
    [CheckPermission(StandardPermission.Catalog.PRODUCTS_CREATE_EDIT_DELETE)]
    public virtual async Task<IActionResult> AssociatedProductDelete(int id)
    {
        //try to get an associated product with the specified id
        var product = await _productService.GetProductByIdAsync(id)

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Reload the associated-products grid before editing so model.Id matches a live record.
  2. Replace the throw with a null check returning Json(new { success = false }) or an error notification so the AJAX call degrades gracefully.
  3. Add a try/catch filter (or the existing ArgumentException filter) to convert these to a structured JSON error instead of a 500.
  4. Audit for concurrent bulk deletes scheduled against the same grouped product.

Example fix

// before
var associatedProduct = await _productService.GetProductByIdAsync(model.Id)
    ?? throw new ArgumentException("No associated product found with the specified id");

// after
var associatedProduct = await _productService.GetProductByIdAsync(model.Id);
if (associatedProduct == null)
    return Json(new { success = false, message = await _localizationService.GetResourceAsync("Admin.Catalog.Products.AssociatedProducts.NotExist") });
Defensive patterns

Strategy: validation

Validate before calling

// In AssociatedProductUpdate, guard before use:
var associatedProduct = await _productService.GetProductByIdAsync(model.Id);
if (associatedProduct == null)
    return Json(new { success = false, message = "Associated product no longer exists." });

Try / catch

// Global filter style for all such admin AJAX throws:
try { /* action body */ }
catch (ArgumentException ex) when (ex.Message.StartsWith("No "))
{
    return Json(new { success = false, message = ex.Message });
}

Prevention

When it happens

Trigger: POST Admin/Product/AssociatedProductUpdate with model.Id for a product that was deleted, or whose ParentGroupedProductId was cleared, before the request landed. Typically a grid row left visible after a concurrent delete or a stale browser tab.

Common situations: Two admin users editing the same grouped product; one removes an associated product while the other reorders the list. Bulk import/delete runs between page load and grid update. Tampered or replayed form posts with an old id.

Related errors


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