nopSolutions/nopCommerce · warning · ArgumentException

No product category mapping found with the specified id

Error message

No product category mapping found with the specified id

What it means

Thrown by CategoryController.ProductUpdate (permission: CATEGORIES_CREATE_EDIT_DELETE). It loads the product-category mapping by model.Id and throws ArgumentException if missing — the mapping was removed or the id is invalid before an update.

Source

Thrown at src/Presentation/Nop.Web/Areas/Admin/Controllers/CategoryController.cs:477

    [CheckPermission(StandardPermission.Catalog.CATEGORIES_VIEW)]
    public virtual async Task<IActionResult> ProductList(CategoryProductSearchModel searchModel)
    {
        //try to get a category with the specified id
        var category = await _categoryService.GetCategoryByIdAsync(searchModel.CategoryId)
            ?? throw new ArgumentException("No category found with the specified id");

        //prepare model
        var model = await _categoryModelFactory.PrepareCategoryProductListModelAsync(searchModel, category);

        return Json(model);
    }

    [CheckPermission(StandardPermission.Catalog.CATEGORIES_CREATE_EDIT_DELETE)]
    public virtual async Task<IActionResult> ProductUpdate(CategoryProductModel model)
    {
        //try to get a product category with the specified id
        var productCategory = await _categoryService.GetProductCategoryByIdAsync(model.Id)
            ?? throw new ArgumentException("No product category mapping found with the specified id");

        //fill entity from product
        productCategory = model.ToEntity(productCategory);
        await _categoryService.UpdateProductCategoryAsync(productCategory);

        return new NullJsonResult();
    }

    [CheckPermission(StandardPermission.Catalog.CATEGORIES_CREATE_EDIT_DELETE)]
    public virtual async Task<IActionResult> ProductDelete(int id)
    {
        //try to get a product category with the specified id
        var productCategory = await _categoryService.GetProductCategoryByIdAsync(id)
            ?? throw new ArgumentException("No product category mapping found with the specified id", nameof(id));

        await _categoryService.DeleteProductCategoryAsync(productCategory);

        return new NullJsonResult();

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Refresh the category product grid and edit only existing mappings.
  2. Make ProductUpdate return a 'record changed' JSON result instead of throwing on a missing mapping.
  3. On the client, warn the user when an update targets a row that no longer exists.

Example fix

// before
var productCategory = await _categoryService.GetProductCategoryByIdAsync(model.Id)
    ?? throw new ArgumentException("No product category mapping found with the specified id");

// after
var productCategory = await _categoryService.GetProductCategoryByIdAsync(model.Id);
if (productCategory == null)
    return Json(new { success = false, reason = "mapping_removed" });
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the mapping exists before updating.
var mapping = await _categoryService.GetProductCategoryByIdAsync(model.Id);
if (mapping == null) return Json(new { success = false, reason = "mapping_removed" });

Type guard

static bool ProductCategoryMappingExists(ProductCategory m) => m is not null;

Try / catch

try { /* ProductUpdate body */ }
catch (ArgumentException)
{
    return Json(new { success = false, reason = "mapping_removed" });
}

Prevention

When it happens

Trigger: POST ProductUpdate with a model.Id that GetProductCategoryByIdAsync cannot resolve: another admin removed the product from the category, or the grid row is stale.

Common situations: Concurrent catalog management; inline-editing a mapping that was just deleted; bulk product reassignment purging the row mid-edit.

Related errors


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