nopSolutions/nopCommerce · error · ArgumentException
Template cannot be loaded
Error message
Template cannot be loaded
What it means
Thrown by WorkflowMessageService.SendTestEmailAsync when _messageTemplateService.GetMessageTemplateByIdAsync(messageTemplateId) returns null. Unlike the order errors this is an ArgumentException (input contract violation) - the caller passed a template id that resolves to no template. Used by the admin 'Send test email' action on the message template editor.
Source
Thrown at src/Libraries/Nop.Services/Messages/WorkflowMessageService.cs:2670
replyToEmailAddress: senderEmail,
replyToName: senderName);
}).ToListAsync();
}
/// <summary>
/// Sends a test email
/// </summary>
/// <param name="messageTemplateId">Message template identifier</param>
/// <param name="sendToEmail">Send to email</param>
/// <param name="tokens">Tokens</param>
/// <param name="languageId">Message language identifier</param>
/// <returns>
/// A task that represents the asynchronous operation
/// The task result contains the queued email identifier
/// </returns>
public virtual async Task<int> SendTestEmailAsync(int messageTemplateId, string sendToEmail, List<Token> tokens, int languageId)
{
var messageTemplate = await _messageTemplateService.GetMessageTemplateByIdAsync(messageTemplateId) ?? throw new ArgumentException("Template cannot be loaded");
//email account
var emailAccount = await GetEmailAccountOfMessageTemplateAsync(messageTemplate, languageId);
//event notification
await _eventPublisher.MessageTokensAddedAsync(messageTemplate, tokens);
return await SendNotificationAsync(messageTemplate, emailAccount, languageId, tokens, sendToEmail, null, ignoreDelayBeforeSend: true);
}
#endregion
#region Common
/// <summary>
/// Get active message templates by the name
/// </summary>
/// <param name="messageTemplateName">Message template name</param>
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Refresh the admin message-template list and reselect the template before sending the test email.
- If the template is genuinely gone, recreate it or restore from a backup/export.
- In custom code calling SendTestEmailAsync, validate the id resolves before invoking.
Example fix
// before
await _workflowMessageService.SendTestEmailAsync(templateId, email, tokens, languageId);
// after
var template = await _messageTemplateService.GetMessageTemplateByIdAsync(templateId);
if (template is null)
return NotFound($"Message template {templateId} not found.");
await _workflowMessageService.SendTestEmailAsync(templateId, email, tokens, languageId); Defensive patterns
Strategy: validation
Validate before calling
var template = await _messageTemplateService.GetMessageTemplateByIdAsync(messageTemplateId);
if (template is null)
return NotFound($"Message template {messageTemplateId} does not exist.");
await _workflowMessageService.SendTestEmailAsync(messageTemplateId, sendToEmail, tokens, languageId); Type guard
async Task<bool> TemplateExistsAsync(int id)
=> id > 0 && await _messageTemplateService.GetMessageTemplateByIdAsync(id) is not null; Try / catch
try
{
await _workflowMessageService.SendTestEmailAsync(messageTemplateId, email, tokens, languageId);
}
catch (ArgumentException ex) when (ex.Message == "Template cannot be loaded")
{
return NotFound("Message template was deleted or does not exist. Refresh the list and retry.");
} Prevention
- Resolve the template id to an entity before calling SendTestEmailAsync.
- Refresh admin views after deleting templates so stale ids are not reused.
- Validate messageTemplateId > 0 and exists in the current store scope before the test-email action.
When it happens
Trigger: Admin clicks 'Send test email' for a template id that was deleted, never existed, or belongs to another store scope. Passing 0 or a stale id from a URL bookmark after the template was removed.
Common situations: Stale admin bookmark to a deleted template; race between two admins where one deletes the template while the other sends a test; import that failed to bring the template row; wrong messageTemplateId wired into a custom controller.
Related errors
- Recipient email is not valid
- Sender email is not valid
- Email is not valid.
- Email cannot be null
- You cannot delete this email account. At least one account i
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/a79e9b18742fff75.
Report an issue: GitHub.