nopSolutions/nopCommerce · error · ArgumentException

No tax category found with the specified id

Error message

No tax category found with the specified id

What it means

Thrown by TaxController.CategoryDelete when ITaxCategoryService.GetTaxCategoryByIdAsync(id) returns null. The action (behind MANAGE_TAX_SETTINGS permission) deletes a tax category by id and aborts with ArgumentException if the lookup fails, before DeleteTaxCategoryAsync is called.

Source

Thrown at src/Presentation/Nop.Web/Areas/Admin/Controllers/TaxController.cs:148

    public virtual async Task<IActionResult> CategoryAdd(TaxCategoryModel model)
    {
        if (!ModelState.IsValid)
            return ErrorJson(ModelState.SerializeErrors());

        var taxCategory = new TaxCategory();
        taxCategory = model.ToEntity(taxCategory);
        await _taxCategoryService.InsertTaxCategoryAsync(taxCategory);

        return Json(new { Result = true });
    }

    [HttpPost]
    [CheckPermission(StandardPermission.Configuration.MANAGE_TAX_SETTINGS)]
    public virtual async Task<IActionResult> CategoryDelete(int id)
    {
        //try to get a tax category with the specified id
        var taxCategory = await _taxCategoryService.GetTaxCategoryByIdAsync(id)
            ?? throw new ArgumentException("No tax category found with the specified id", nameof(id));

        await _taxCategoryService.DeleteTaxCategoryAsync(taxCategory);

        return new NullJsonResult();
    }

    #endregion

    #endregion
}

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Refresh the tax categories list; the category is already deleted and no further action is required.
  2. Guard the UI with a single-click delete and post-delete grid refresh.
  3. For API callers, treat a null lookup as idempotent success (already deleted) rather than an error.
  4. Wrap the action to return a benign NullJsonResult when the category is absent.

Example fix

// before
var taxCategory = await _taxCategoryService.GetTaxCategoryByIdAsync(id)
    ?? throw new ArgumentException("No tax category found with the specified id", nameof(id));
await _taxCategoryService.DeleteTaxCategoryAsync(taxCategory);

// after
var taxCategory = await _taxCategoryService.GetTaxCategoryByIdAsync(id);
if (taxCategory is null)
    return new NullJsonResult(); // idempotent
Defensive patterns

Strategy: validation

Validate before calling

var taxCategory = await _taxCategoryService.GetTaxCategoryByIdAsync(id);
if (taxCategory is null)
    return; // already deleted — idempotent

Try / catch

try { await taxController.CategoryDelete(id); }
catch (ArgumentException ex) when (ex.Message.Contains("No tax category found"))
{ /* already removed — no-op */ }

Prevention

When it happens

Trigger: Deleting a tax category that was already removed by another request or session. A double-click on the delete control. A programmatic delete with an id referencing a row removed during a tax-config migration or reset.

Common situations: Two admin tabs both viewing the tax categories list; one deletes a category and the other attempts the same delete. A plugin or upgrade merges/renumbers tax categories, invalidating the cached grid id. The default tax category was deleted and the id is stale.

Related errors


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