nopSolutions/nopCommerce · error · Exception
"{tName}" template could not be loaded
Error message
"{tName}" template could not be loaded What it means
Thrown by getProductTemplate inside sample-product installation. It caches entity IDs by name via getAndSaveId; if GetFirstEntityIdAsync<ProductTemplate> returns null for the given template name, no product can reference that template, so it throws. This means a referenced product template name was never seeded, indicating sample data prerequisites (the base install that creates templates) were skipped or mismatch.
Source
Thrown at src/Libraries/Nop.Services/Installation/InstallSampleData.Products.cs:127
async Task<int> getAndSaveId(Dictionary<string, int> dict, string key, Func<string, Task<int>> foo)
{
if (string.IsNullOrEmpty(key))
return 0;
if (dict.TryGetValue(key, out var id))
return id;
id = await foo(key);
dict[key] = id;
return id;
}
async Task<int> getProductTemplate(string templateName)
{
return await getAndSaveId(productTemplates, templateName,
async tName => await GetFirstEntityIdAsync<ProductTemplate>(pt => pt.Name == tName) ??
throw new Exception($"\"{tName}\" template could not be loaded"));
}
async Task<int> getTaxCategoryId(string taxCategoryName)
{
return await getAndSaveId(taxCategories, taxCategoryName, async tcName => await GetFirstEntityIdAsync<TaxCategory>(tc => tc.Name == tcName) ??
throw new Exception($"\"{tcName}\" tax category could not be loaded"));
}
async Task<int> getCategoryId(string categoryName)
{
return await getAndSaveId(categories, categoryName, async cName => await GetFirstEntityIdAsync<Category>(c => c.Name == cName) ??
throw new Exception($"\"{cName}\" category could not be loaded"));
}
async Task<int> getManufacturerId(string manufacturerName)
{
return await getAndSaveId(manufacturers, manufacturerName, async mName => await GetFirstEntityIdAsync<Manufacturer>(m => m.Name == mName) ??
throw new Exception($"\"{mName}\" manufacturer could not be loaded"));View on GitHub (pinned to 64bdf2ff08)
Solutions
- Run the base installer (which seeds product templates) before installing sample product data.
- Verify the ProductTemplate names referenced in the sample data exist in the DB.
- Fix typos in template names in the sample-data source.
- Reinstall from a clean database to ensure prerequisites are present.
Example fix
// before
return await getAndSaveId(productTemplates, templateName,
async tName => await GetFirstEntityIdAsync<ProductTemplate>(pt => pt.Name == tName)
?? throw new Exception($"\"{tName}\" template could not be loaded"));
// after - list available templates on failure to aid debugging
var id = await GetFirstEntityIdAsync<ProductTemplate>(pt => pt.Name == templateName);
if (id == 0)
throw new InvalidOperationException($"Product template '{templateName}' not found. Seed product templates first."); Defensive patterns
Strategy: validation
Validate before calling
// Verify each referenced product template name exists before sample install
var needed = new[] { "Simple product", "Grouped product" };
var missing = needed.Except(await Table<ProductTemplate>().Select(pt => pt.Name).ToListAsync());
if (missing.Any())
throw new InvalidOperationException($"Missing product templates: {string.Join(", ", missing)}"); Type guard
static async Task<bool> ProductTemplateExistsAsync(IRepository<ProductTemplate> repo, string name)
=> await repo.Table.AnyAsync(pt => pt.Name == name); Try / catch
try { await getProductTemplate(templateName); }
catch (Exception ex) when (ex.Message.Contains("template could not be loaded"))
{ /* log the missing name and the available templates, then abort sample install */ } Prevention
- Run the base install (which seeds product templates) before sample data.
- Keep template names in sample data in sync with seeded names.
- Reinstall from a clean DB.
When it happens
Trigger: Installing sample product data that references a ProductTemplate by name when that template does not exist; running sample-data install without the base installation that seeds product templates; a typo in the template name in the sample data.
Common situations: Sample data installed against an incomplete base install; template names changed between versions; a custom sample-data file using template names not present in the DB.
Related errors
- "{tcName}" tax category could not be loaded
- "{cName}" category could not be loaded
- "{mName}" manufacturer could not be loaded
- Default email account cannot be loaded
- No default store could be loaded
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/8c65867b0327950c.
Report an issue: GitHub.