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

  1. Refresh the admin message-template list and reselect the template before sending the test email.
  2. If the template is genuinely gone, recreate it or restore from a backup/export.
  3. 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

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


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