microsoft/semantic-kernel · warning · InvalidOperationException
A helper with the name '{helperName}' is already registered.
Error message
A helper with the name '{helperName}' is already registered. What it means
Thrown when attempting to register a Handlebars helper whose name already exists in the Handlebars configuration's Helpers dictionary. RegisterHelperSafe guards against silent overwrites of existing helpers.
Source
Thrown at dotnet/src/Extensions/PromptTemplates.Handlebars/Helpers/KernelHelperUtils.cs:26
namespace Microsoft.SemanticKernel.PromptTemplates.Handlebars.Helpers;
/// <summary>
/// Extension class to register additional helpers as Kernel System helpers.
/// </summary>
internal static class KernelHelpersUtils
{
/// <summary>
/// Registers a helper with the Handlebars instance, throwing an exception if a helper with the same name is already registered.
/// </summary>
/// <param name="handlebarsInstance">The <see cref="IHandlebars"/>-instance.</param>
/// <param name="helperName">The name of the helper.</param>
/// <param name="helper">The helper to register.</param>
internal static void RegisterHelperSafe(IHandlebars handlebarsInstance, string helperName, HandlebarsReturnHelper helper)
{
if (handlebarsInstance.Configuration.Helpers.ContainsKey(helperName))
{
throw new InvalidOperationException($"A helper with the name '{helperName}' is already registered.");
}
handlebarsInstance.RegisterHelper(helperName, helper);
}
/// <summary>
/// Returns value if defined, else, tries to resolve value from given KernelArguments dictionary.
/// </summary>
/// <param name="argument">Argument to process.</param>
/// <param name="kernelArguments">Dictionary of variables maintained by the Handlebars context.</param>
internal static object? GetArgumentValue(object argument, KernelArguments kernelArguments)
{
// If the argument is of type UndefinedBindingResult, it means that Handlebars attempted to retrieve the value for a binding
// but was unable to do so because the variable was not defined or not passed to the template context at the time of render.
// Thus, we try to get the value from the kernel arguments dictionary.
if (argument is UndefinedBindingResult result)
{
return kernelArguments.TryGetValue(result.Value, out var variable) ? variable : null;View on GitHub (pinned to c028a0c7dc)
Solutions
- Choose a unique helper name (prefix with your plugin/namespace) to avoid collisions.
- Before registering, check handlebarsInstance.Configuration.Helpers.ContainsKey(name) and skip or replace deliberately.
- Initialize helpers only once per Handlebars instance lifetime.
Example fix
// before
KernelHelpersUtils.RegisterHelperSafe(handlebars, "message", helper);
KernelHelpersUtils.RegisterHelperSafe(handlebars, "message", other); // throws
// after
if (!handlebars.Configuration.Helpers.ContainsKey("myPlugin_message"))
{
KernelHelpersUtils.RegisterHelperSafe(handlebars, "myPlugin_message", helper);
} Defensive patterns
Strategy: validation
Validate before calling
if (handlebars.Configuration.Helpers.ContainsKey(helperName))
throw new InvalidOperationException($"Helper '{helperName}' already registered; choose a unique name.");
KernelHelpersUtils.RegisterHelperSafe(handlebars, helperName, helper); Type guard
public static bool IsHelperRegistered(IHandlebars handlebars, string name) =>
handlebars.Configuration.Helpers.ContainsKey(name); Try / catch
try
{
KernelHelpersUtils.RegisterHelperSafe(handlebars, name, helper);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("already registered"))
{
_logger.LogWarning("Helper '{Name}' already registered; skipping.", name);
} Prevention
- Namespace-prefix custom helper names to avoid collisions.
- Check Helpers.ContainsKey before registering.
- Initialize helpers once per Handlebars instance.
When it happens
Trigger: KernelHelpersUtils.RegisterHelperSafe is called with a helperName that already has an entry in handlebarsInstance.Configuration.Helpers, e.g., registering the same helper twice or using a name that collides with a built-in.
Common situations: Registering a custom helper with a name that clashes with a system helper (e.g., 'message'), re-registering helpers across multiple initialization calls without checking existence, or plugin name collisions.
Related errors
- Argument '{propertyName}' has a value that doesn't support a
- No arguments are provided for {fullyResolvedFunctionName}.
- Invalid argument type for function {functionMetadata.Name}.
- Parameter {param.Name} is required for function {functionMet
- Invalid parameter type for function {functionMetadata.Name}.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/f51dedf5fd34b3d7.
Report an issue: GitHub.