{"record":{"id":"3e523b39a0049604","repo":"elsa-workflows/elsa-core","slug":"there-is-no-handler-to-handle-the-commandtype-fullname","errorCode":null,"errorMessage":"There is no handler to handle the {commandType.FullName} command","messagePattern":"There is no handler to handle the (.+?) command","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/common/Elsa.Mediator/Middleware/Command/Components/CommandHandlerInvokerMiddleware.cs","lineNumber":30,"sourceCode":"/// </summary>\n[UsedImplicitly]\npublic class CommandHandlerInvokerMiddleware(CommandMiddlewareDelegate next) : ICommandMiddleware\n{\n    /// <inheritdoc />\n    [UnconditionalSuppressMessage(\"Trimming\", \"IL2060:Call to MakeGenericMethod can not be statically analyzed\", Justification = \"The result type is determined at runtime from command types and handlers are registered in DI.\")]\n    public async ValueTask InvokeAsync(CommandContext context)\n    {\n        // Find all handlers for the specified command.\n        var command = context.Command;\n        var commandType = command.GetType();\n        var resultType = context.ResultType;\n        var handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, resultType);\n        var serviceProvider = context.ServiceProvider;\n        var commandHandlers = serviceProvider.GetServices<ICommandHandler>();\n        var handlers = commandHandlers.DistinctBy(x => x.GetType()).Where(x => handlerType.IsInstanceOfType(x)).ToArray();\n\n        if (handlers.Length == 0)\n            throw new InvalidOperationException($\"There is no handler to handle the {commandType.FullName} command\");\n\n        if (handlers.Length > 1)\n            throw new InvalidOperationException($\"Multiple handlers were found to handle the {commandType.FullName} command\");\n\n        var handler = handlers.First();\n        var strategyContext = new CommandStrategyContext(context, handler, serviceProvider, context.CancellationToken);\n        var strategy = context.CommandStrategy;\n        var executeMethod = strategy.GetType().GetMethod(nameof(ICommandStrategy.ExecuteAsync))!;\n        var executeMethodWithReturnType = executeMethod.MakeGenericMethod(resultType);\n\n        // Execute command.\n        var task = (Task)executeMethodWithReturnType.Invoke(strategy, [strategyContext])!;\n\n        // Wait for completion.\n        await task;\n\n        // Get the result of the task.\n        var taskWithReturnType = typeof(Task<>).MakeGenericType(resultType);","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/common/Elsa.Mediator/Middleware/Command/Components/CommandHandlerInvokerMiddleware.cs#L12-L48","documentation":"Elsa.Mediator's command pipeline resolves exactly one ICommandHandler<TCommand,TResult> from DI for each command being sent. This error is thrown when zero handlers matching the command's type and expected result type are found among the registered ICommandHandler services. It means the command was dispatched but no handler was ever registered in the dependency injection container.","triggerScenarios":"Calling IMediator.SendAsync (or ICommandSender) with a command type for which no class implementing ICommandHandler<ThatCommand, TResult> was registered in the service provider; registering the handler with a mismatched TResult so handlerType.IsInstanceOfType fails; forgetting to call AddCommandHandler<THandler>() / AddHandlersFrom<TAssembly>() during host configuration.","commonSituations":"Developers add a new command and handler but forget DI registration; handler registered for the wrong result type (e.g. ICommandHandler<MyCommand, Unit> vs ICommandHandler<MyCommand, MyResult>); handler registered in a different service collection than the one the mediator resolves from (test host vs app host); assembly scanning misses the handler's namespace; renaming a handler type breaks an explicit registration.","solutions":["Register a handler for the command: services.AddCommandHandler<MyCommandHandler>() (or AddHandlersFrom<MarkerTypeInHandlersAssembly>()).","Verify the handler implements exactly ICommandHandler<TCommand, TResult> with TCommand equal to the sent command's type and TResult equal to the expected ResultType of the Send call.","Confirm the mediator and the handler are registered on the same IServiceCollection / service provider instance that is resolving services.","Check that assembly scanning includes the assembly containing the handler and that the handler is public (non-abstract).","If the command should not require a handler, ensure you are not sending it accidentally (e.g. wrong message type passed to SendAsync instead of PublishAsync)."],"exampleFix":"// before\nservices.AddMediator();\nawait mediator.SendAsync(new CreateOrderCommand(order)); // throws: no handler\n\n// after\nservices.AddMediator();\nservices.AddCommandHandler<CreateOrderCommandHandler>(); // implements ICommandHandler<CreateOrderCommand, Order>","handlingStrategy":"validation","validationCode":"// Before sending, verify a handler is registered:\nvar handlerType = typeof(ICommandHandler<,>).MakeGenericType(command.GetType(), typeof(TResult));\nvar hasHandler = serviceProvider.GetServices<Elsa.Mediator.Contracts.ICommandHandler>()\n    .Any(h => handlerType.IsInstanceOfType(h));\nif (!hasHandler)\n    throw new InvalidOperationException($\"No handler registered for {command.GetType().Name}; call AddCommandHandler<...>() first.\");","typeGuard":"static bool HasHandler<TCommand, TResult>(IServiceProvider sp) =>\n    sp.GetServices<Elsa.Mediator.Contracts.ICommandHandler>().Any(h =>\n        h is Elsa.Mediator.Contracts.ICommandHandler<TCommand, TResult>);","tryCatchPattern":"try\n{\n    await mediator.SendAsync(command, cancellationToken);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"There is no handler to handle\"))\n{\n    logger.LogError(ex, \"Missing handler for {Command}\", command.GetType().Name);\n    throw;\n}","preventionTips":["Use assembly scanning (AddHandlersFrom<TMarker>()) so new handlers register automatically.","Pair every command type with its handler in the same feature/dependency-registration file.","Write a startup test asserting every ICommand implementation has exactly one registered handler.","Keep the handler's TResult identical to the generic argument used in SendAsync."],"tags":["mediator","dependency-injection","command-handling","registration"],"backgroundTag":"missing-dependency","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}