{"record":{"id":"787d5571f6b0211c","repo":"elsa-workflows/elsa-core","slug":"multiple-invoke-methods-were-found-use-either-invoke-or-787d55","errorCode":null,"errorMessage":"Multiple Invoke methods were found. Use either Invoke or InvokeAsync.","messagePattern":"Multiple Invoke methods were found\\. Use either Invoke or InvokeAsync\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Workflows.Core/Pipelines/MiddlewareHelpers.cs","lineNumber":17,"sourceCode":"using System.Reflection;\n\nnamespace Elsa.Workflows.Pipelines;\n\npublic static class MiddlewareHelpers\n{\n    public static MethodInfo GetInvokeMethod(Type middleware)\n    {\n        const string invokeMethodName = \"Invoke\";\n        const string invokeAsyncMethodName = \"InvokeAsync\";\n        var methods = middleware.GetMethods(BindingFlags.Instance | BindingFlags.Public);\n        var invokeMethods = methods.Where(m => string.Equals(m.Name, invokeMethodName, StringComparison.Ordinal) || string.Equals(m.Name, invokeAsyncMethodName, StringComparison.Ordinal)).ToArray();\n\n        switch (invokeMethods.Length)\n        {\n            case > 1:\n                throw new InvalidOperationException(\"Multiple Invoke methods were found. Use either Invoke or InvokeAsync.\");\n            case 0:\n                throw new InvalidOperationException(\"No Invoke methods were found. Use either Invoke or InvokeAsync\");\n        }\n\n        var methodInfo = invokeMethods[0];\n\n        if (!typeof(Task).IsAssignableFrom(methodInfo.ReturnType) && !typeof(ValueTask).IsAssignableFrom(methodInfo.ReturnType))\n            throw new InvalidOperationException($\"The {methodInfo.Name} method must return Task or ValueTask\");\n\n        return methodInfo;\n    }\n}","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Workflows.Core/Pipelines/MiddlewareHelpers.cs#L1-L29","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Keep exactly one public instance method named Invoke or InvokeAsync and delete/rename the other","Rename extra overloads to helper method names not starting with Invoke","Move shared logic into a private method and keep a single entry point"],"exampleFix":"// before\npublic Task InvokeAsync(Context ctx) => Handle(ctx);\npublic Task Invoke(Context ctx) => Handle(ctx);\n// after\npublic Task InvokeAsync(Context ctx) => Handle(ctx);","handlingStrategy":"validation","validationCode":"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.\");","typeGuard":null,"tryCatchPattern":"try { pipelines.UseMiddleware<TMiddleware>(); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"Multiple Invoke methods\")) { /* fix middleware shape */ }","preventionTips":["Keep exactly one public Invoke/InvokeAsync entry point per middleware","Rename helper overloads so they don't start with Invoke"],"tags":["middleware","reflection","pipeline"],"backgroundTag":"invalid-argument-value","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}