elsa-workflows/elsa-core · error · InvalidOperationException

Multiple Invoke methods were found. Use either Invoke or…

Error message

Multiple Invoke methods were found. Use either Invoke or InvokeAsync.

What it means

MiddlewareHelpers.GetInvokeMethod reflects over a middleware type to find its Invoke or InvokeAsync method (ASP.NET-style middleware convention). If more than one such method exists it throws InvalidOperationException, since the invocation contract would be ambiguous. The comparison is ordinal on instance public methods.

Solutions

  1. Keep exactly one public instance method named Invoke or InvokeAsync and delete/rename the other
  2. Rename extra overloads to helper method names not starting with Invoke
  3. Move shared logic into a private method and keep a single entry point

Example fix

// before
public Task InvokeAsync(Context ctx) => Handle(ctx);
public Task Invoke(Context ctx) => Handle(ctx);
// after
public Task InvokeAsync(Context ctx) => Handle(ctx);
Defensive patterns

Strategy: validation

Validate before calling

var count = typeof(TMiddleware).GetMethods(BindingFlags.Instance | BindingFlags.Public).Count(m => m.Name is "Invoke" or "InvokeAsync"); if (count > 1) throw new InvalidOperationException("Middleware must define only one Invoke/InvokeAsync.");

Try / catch

try { pipelines.UseMiddleware<TMiddleware>(); } catch (InvalidOperationException ex) when (ex.Message.Contains("Multiple Invoke methods")) { /* fix middleware shape */ }

Prevention

When it happens

Trigger: Defining a middleware class with both an Invoke and an InvokeAsync method (or overloads named Invoke), then registering it in an Elsa pipeline via UseMiddleware-style registration that calls GetInvokeMethod.

Common situations: Refactoring a middleware from Invoke to InvokeAsync while leaving the old method in place; overload sets like Invoke(A) and Invoke(A, B) that both match by name.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Pipelines/MiddlewareHelpers.cs:17

using System.Reflection;

namespace Elsa.Workflows.Pipelines;

public static class MiddlewareHelpers
{
    public static MethodInfo GetInvokeMethod(Type middleware)
    {
        const string invokeMethodName = "Invoke";
        const string invokeAsyncMethodName = "InvokeAsync";
        var methods = middleware.GetMethods(BindingFlags.Instance | BindingFlags.Public);
        var invokeMethods = methods.Where(m => string.Equals(m.Name, invokeMethodName, StringComparison.Ordinal) || string.Equals(m.Name, invokeAsyncMethodName, StringComparison.Ordinal)).ToArray();

        switch (invokeMethods.Length)
        {
            case > 1:
                throw new InvalidOperationException("Multiple Invoke methods were found. Use either Invoke or InvokeAsync.");
            case 0:
                throw new InvalidOperationException("No Invoke methods were found. Use either Invoke or InvokeAsync");
        }

        var methodInfo = invokeMethods[0];

        if (!typeof(Task).IsAssignableFrom(methodInfo.ReturnType) && !typeof(ValueTask).IsAssignableFrom(methodInfo.ReturnType))
            throw new InvalidOperationException($"The {methodInfo.Name} method must return Task or ValueTask");

        return methodInfo;
    }
}

View on GitHub (pinned to fe9217bdfa)