LuckyPennySoftware/MediatR · error · InvalidOperationException
Did not return a Task from the exception handler.
Error message
Did not return a Task from the exception handler.
What it means
Thrown at runtime by RequestExceptionProcessorBehavior when an exception handler's Handle method (invoked via reflection) returns null instead of a Task. The handler contract is IRequestExceptionHandler<TRequest,TResponse,TException>.Handle returning Task and setting state.Handled; null violates it.
Source
Thrown at src/MediatR/Pipeline/RequestExceptionProcessorBehavior.cs:50
catch (Exception exception)
{
var state = new RequestExceptionHandlerState<TResponse>();
var exceptionTypes = GetExceptionTypes(exception.GetType());
var handlersForException = exceptionTypes
.SelectMany(exceptionType => GetHandlersForException(exceptionType, request))
.GroupBy(static handlerForException => handlerForException.Handler.GetType())
.Select(static handlerForException => handlerForException.First())
.Select(static handlerForException => (MethodInfo: GetMethodInfoForHandler(handlerForException.ExceptionType), handlerForException.Handler))
.ToList();
foreach (var handlerForException in handlersForException)
{
try
{
await ((Task) (handlerForException.MethodInfo.Invoke(handlerForException.Handler, new object[] { request, exception, state, cancellationToken })
?? throw new InvalidOperationException("Did not return a Task from the exception handler."))).ConfigureAwait(false);
}
catch (TargetInvocationException invocationException) when (invocationException.InnerException != null)
{
// Unwrap invocation exception to throw the actual error
ExceptionDispatchInfo.Capture(invocationException.InnerException).Throw();
}
if (state.Handled)
{
break;
}
}
if (!state.Handled)
{
throw;
}
View on GitHub (pinned to 916ef1b3d6)
Solutions
- Make Handle always return a non-null Task; use `async Task` and never return null, or `return Task.CompletedTask;` for sync.
- If you intend not to handle the exception, set state.Handled = false and return Task.CompletedTask instead of null.
- Add a unit test asserting Handle returns non-null for all code paths.
Example fix
// before
public class MyHandler : IRequestExceptionHandler<MyReq, MyResp, MyException>
{
public Task Handle(MyReq req, MyException ex,
RequestExceptionHandlerState<MyResp> state, CancellationToken ct)
=> null;
}
// after
public class MyHandler : IRequestExceptionHandler<MyReq, MyResp, MyException>
{
public async Task Handle(MyReq req, MyException ex,
RequestExceptionHandlerState<MyResp> state, CancellationToken ct)
{
state.SetHandled(new MyResp());
await Task.CompletedTask;
}
} Defensive patterns
Strategy: validation
Validate before calling
// Unit test that every IRequestExceptionHandler.Handle returns a non-null Task
[Fact]
public async Task Handle_ReturnsTask()
{
var sut = new MyExceptionHandler();
var state = new RequestExceptionHandlerState<MyResponse>();
var task = sut.Handle(new MyRequest(), new MyException(), state, default);
Assert.NotNull(task);
await task;
} Try / catch
try { await mediator.Send(request, ct); }
catch (InvalidOperationException ex) when (ex.Message == "Did not return a Task from the exception handler.")
{
logger.LogError(ex, "Exception handler returned null Task");
throw;
} Prevention
- Always set state.SetHandled(...) and return a Task from Handle.
- Use async Task signature so all paths return a Task.
When it happens
Trigger: An IRequestExceptionHandler implementation whose Handle returns null (e.g. `return null;`, `return default;`, or an async method whose code path returns null).
Common situations: Custom exception handler with a missed return path; copy-pasting a void-style handler into a Task-returning signature; dynamic/generated handler that misbehaves.
Related errors
- Could not create task for action method {actionForException.
- Could not find method {nameof(IRequestExceptionHandler<TRequ
- Could not find method {nameof(IRequestExceptionAction<TReque
- Open behavior type can not be null.
- The type "{openBehaviorType.Name}" must implement IPipelineB
AI-assisted analysis of LuckyPennySoftware/MediatR@916ef1b3d6 (2026-08-13).
Data as JSON: /api/errors/f2c67e470bcaeafe.
Report an issue: GitHub.