nopSolutions/nopCommerce · error · ArgumentException

Admin.Catalog.Products.Import.ProductAttributesDontExist

Error message

Admin.Catalog.Products.Import.ProductAttributesDontExist

What it means

Thrown during product XLSX import when product-attribute IDs referenced in the spreadsheet do not exist in the database. nopCommerce batches all referenced attribute IDs into one SQL check (GetNotExistingAttributesAsync) and aborts the whole import with an ArgumentException listing the missing IDs.

Source

Thrown at src/Libraries/Nop.Services/ExportImport/ImportManager.cs:1442

            productsInFile.Add(endRow);

            endRow++;
        }

        //performance optimization, the check for the existence of the categories in one SQL request
        var notExistingCategories = await _categoryService.GetNotExistingCategoriesAsync(allCategories.ToArray());
        if (notExistingCategories.Any())
            throw new ArgumentException(string.Format(await _localizationService.GetResourceAsync("Admin.Catalog.Products.Import.CategoriesDontExist"), string.Join(", ", notExistingCategories)));

        //performance optimization, the check for the existence of the manufacturers in one SQL request
        var notExistingManufacturers = await _manufacturerService.GetNotExistingManufacturersAsync(allManufacturers.ToArray());
        if (notExistingManufacturers.Any())
            throw new ArgumentException(string.Format(await _localizationService.GetResourceAsync("Admin.Catalog.Products.Import.ManufacturersDontExist"), string.Join(", ", notExistingManufacturers)));

        //performance optimization, the check for the existence of the product attributes in one SQL request
        var notExistingProductAttributes = await _productAttributeService.GetNotExistingAttributesAsync(allAttributeIds.ToArray());
        if (notExistingProductAttributes.Any())
            throw new ArgumentException(string.Format(await _localizationService.GetResourceAsync("Admin.Catalog.Products.Import.ProductAttributesDontExist"), string.Join(", ", notExistingProductAttributes)));

        //performance optimization, the check for the existence of the specification attribute options in one SQL request
        var notExistingSpecificationAttributeOptions = await _specificationAttributeService.GetNotExistingSpecificationAttributeOptionsAsync(allSpecificationAttributeOptionIds.Where(saoId => saoId != 0).ToArray());
        if (notExistingSpecificationAttributeOptions.Any())
            throw new ArgumentException($"The following specification attribute option ID(s) don't exist - {string.Join(", ", notExistingSpecificationAttributeOptions)}");

        //performance optimization, the check for the existence of the stores in one SQL request
        var notExistingStores = await _storeService.GetNotExistingStoresAsync(allStores.ToArray());
        if (notExistingStores.Any())
            throw new ArgumentException(string.Format(await _localizationService.GetResourceAsync("Admin.Catalog.Products.Import.StoresDontExist"), string.Join(", ", notExistingStores)));

        return new ImportProductMetadata
        {
            EndRow = endRow,
            Manager = manager,
            Properties = defaultProperties,
            ProductsInFile = productsInFile,
            ProductAttributeManager = productAttributeManager,

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Pre-create the missing product attributes in Catalog > Attributes > Product Attributes and capture their IDs, then update the spreadsheet or re-run.
  2. Export the current attributes and confirm the IDs in the file match real rows.
  3. Remove attribute mappings from rows that reference non-existent attribute IDs.
  4. When migrating between environments, migrate product attributes before products.

Example fix

// before
await _importManager.ImportProductsFromXlsxAsync(stream);

// after — validate attribute IDs up front
var validIds = (await _productAttributeService.GetAllProductAttributesAsync()).Select(a => a.Id).ToHashSet();
var badIds = referencedAttributeIds.Where(id => !validIds.Contains(id)).ToList();
if (badIds.Any())
    return BadRequest($"These product attribute IDs do not exist: {string.Join(", ", badIds)}");
await _importManager.ImportProductsFromXlsxAsync(stream);
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate product attribute IDs referenced in the import
var validIds = (await _productAttributeService.GetAllProductAttributesAsync()).Select(a => a.Id).ToHashSet();
var bad = referencedAttributeIds.Where(id => !validIds.Contains(id)).ToList();
if (bad.Any())
    return BadRequest($"These product attribute IDs do not exist: {string.Join(", ", bad)}");
await _importManager.ImportProductsFromXlsxAsync(stream);

Try / catch

try { await _importManager.ImportProductsFromXlsxAsync(stream); }
catch (ArgumentException ex) when (ex.Message.Contains("ProductAttributesDontExist"))
{ /* show the missing attribute IDs to the user */ }

Prevention

When it happens

Trigger: Calling the product-import path with an XLSX whose product-attribute columns reference attribute IDs that have no matching record in the DB. Fires after the category/manufacturer checks, before ImportProductMetadata is returned.

Common situations: Spreadsheet uses numeric attribute IDs from another environment whose attributes were never migrated; an attribute was deleted after export; IDs were hand-edited incorrectly; importing against a fresh DB.

Related errors


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