elsa-workflows/elsa-core · error · InvalidOperationException

Output converter ID ' ' is registered more than once or…

Error message

Output converter ID '{duplicate.Key}' is registered more than once or differs from another registration only by case.

What it means

Thrown by OutputConverterRegistry.ValidateRegistrations when two or more output converter registrations share the same descriptor Id, including IDs that differ only by letter case (grouped with OrdinalIgnoreCase). Converter IDs must be unique case-insensitively so registry lookups are unambiguous.

Solutions

  1. Give each converter a unique Id, e.g. namespace-qualified like 'MyCompany.IntToString'.
  2. Remove duplicate registrations (check whether the module/feature is being added twice).
  3. Audit installed packages for converters using the same Id and prefer one, overriding the other intentionally.

Example fix

// before
descriptor.Id = "int-to-string"; // in ModuleA
descriptor.Id = "Int-To-String"; // in ModuleB

// after
descriptor.Id = "ModuleA.IntToString";
descriptor.Id = "ModuleB.IntToString";
Defensive patterns

Strategy: validation

Validate before calling

var ids = registrations.Select(r => r.Descriptor.Id).ToList();
var dupes = ids.GroupBy(i => i, StringComparer.OrdinalIgnoreCase).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
if (dupes.Any()) throw new InvalidOperationException($"Duplicate converter Ids: {string.Join(", ", dupes)}");

Try / catch

try
{
    host = builder.Build(); // registry validated during startup
}
catch (InvalidOperationException ex) when (ex.Message.Contains("registered more than once"))
{
    logger.LogCritical(ex, "Duplicate output converter Ids detected; check installed modules");
    throw;
}

Prevention

When it happens

Trigger: Registering two OutputConverterDescriptors with the same Id (e.g., 'int-to-string' registered twice, or 'IntToString' and 'inttostring' in different modules), often when a module is added twice or two packages define overlapping converters.

Common situations: Loading two versions of a plugin assembly, duplicating a feature's DI registrations, and two teams independently picking the same converter Id.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/db71af87c5974d81. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Services/OutputConverterRegistry.cs:61

    }

    private static void ValidateRegistrations(IReadOnlyCollection<OutputConverterRegistration> registrations)
    {
        foreach (var registration in registrations)
        {
            ValidateDescriptor(registration.Descriptor);
            var id = registration.Descriptor.Id;

            if (!string.Equals(id, registration.ServiceKey, StringComparison.Ordinal))
                throw new InvalidOperationException($"Output converter registration '{id}' must use the Converter ID as its service key.");
        }

        var duplicate = registrations
            .GroupBy(x => x.Descriptor.Id, StringComparer.OrdinalIgnoreCase)
            .FirstOrDefault(x => x.Count() > 1);

        if (duplicate != null)
            throw new InvalidOperationException($"Output converter ID '{duplicate.Key}' is registered more than once or differs from another registration only by case.");
    }

    internal static void ValidateDescriptor(OutputConverterDescriptor descriptor)
    {
        if (string.IsNullOrWhiteSpace(descriptor.Id))
            throw new InvalidOperationException("Output converter IDs cannot be empty.");

        if (descriptor.SourceType.ContainsGenericParameters || descriptor.ResultType.ContainsGenericParameters)
            throw new InvalidOperationException($"Output converter '{descriptor.Id}' cannot use open-generic source or result types.");
    }
}

View on GitHub (pinned to fe9217bdfa)