LuckyPennySoftware/MediatR · error · InvalidOperationException
{implementationType.Name} must implement {typeof(IRequestPos
Error message
{implementationType.Name} must implement {typeof(IRequestPostProcessor<,>).FullName} What it means
Thrown by AddRequestPostProcessor when a closed implementation type does not close IRequestPostProcessor<TRequest,TResponse> for any pair. FindInterfacesThatClose walks the type graph and finds no matching closed interface, so no ServiceDescriptor can be created.
Source
Thrown at src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs:478
/// <typeparam name="TImplementationType">Closed request post processor implementation type</typeparam>
/// <param name="serviceLifetime">Optional service lifetime, defaults to <see cref="ServiceLifetime.Transient"/>.</param>
/// <returns>This</returns>
public MediatRServiceConfiguration AddRequestPostProcessor<TImplementationType>(ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
=> AddRequestPostProcessor(typeof(TImplementationType), serviceLifetime);
/// <summary>
/// Register a closed request post processor type against all <see cref="IRequestPostProcessor{TRequest,TResponse}"/> implementations
/// </summary>
/// <param name="implementationType">Closed request post processor implementation type</param>
/// <param name="serviceLifetime">Optional service lifetime, defaults to <see cref="ServiceLifetime.Transient"/>.</param>
/// <returns>This</returns>
public MediatRServiceConfiguration AddRequestPostProcessor(Type implementationType, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
{
var implementedGenericInterfaces = implementationType.FindInterfacesThatClose(typeof(IRequestPostProcessor<,>)).ToList();
if (implementedGenericInterfaces.Count == 0)
{
throw new InvalidOperationException($"{implementationType.Name} must implement {typeof(IRequestPostProcessor<,>).FullName}");
}
foreach (var implementedPostProcessorType in implementedGenericInterfaces)
{
RequestPostProcessorsToRegister.Add(new ServiceDescriptor(implementedPostProcessorType, implementationType, serviceLifetime));
}
return this;
}
/// <summary>
/// Registers an open request post processor type against the <see cref="IRequestPostProcessor{TRequest,TResponse}"/> open generic interface type
/// </summary>
/// <param name="openBehaviorType">An open generic request post processor type</param>
/// <param name="serviceLifetime">Optional service lifetime, defaults to <see cref="ServiceLifetime.Transient"/>.</param>
/// <returns>This</returns>
public MediatRServiceConfiguration AddOpenRequestPostProcessor(Type openBehaviorType, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
{
if (!openBehaviorType.IsGenericType)
View on GitHub (pinned to 916ef1b3d6)
Solutions
- Make the class a closed post-processor: class MyProcessor : IRequestPostProcessor<MyRequest, MyResponse>.
- If the class is generic across request/response, use AddOpenRequestPostProcessor(typeof(MyProcessor<,>)).
- Verify arity: post-processor is IRequestPostProcessor<TRequest,TResponse> (two parameters).
Example fix
// before
public class MyProcessor : IRequestPreProcessor<MyRequest> { ... }
cfg.AddRequestPostProcessor(typeof(MyProcessor));
// after
public class MyProcessor : IRequestPostProcessor<MyRequest, MyResponse>
{
public Task Process(MyRequest req, MyResponse resp, CancellationToken ct)
=> Task.CompletedTask;
}
cfg.AddRequestPostProcessor(typeof(MyProcessor)); Defensive patterns
Strategy: validation
Validate before calling
static bool IsClosedPostProcessor(Type t) =>
t.IsConcrete() &&
t.FindInterfacesThatClose(typeof(IRequestPostProcessor<,>)).Any();
if (IsClosedPostProcessor(typeof(MyProcessor)))
cfg.AddRequestPostProcessor(typeof(MyProcessor)); Type guard
static bool IsClosedPostProcessor(Type t) =>
t.IsConcrete() &&
t.FindInterfacesThatClose(typeof(IRequestPostProcessor<,>)).Any(); Prevention
- Post-processors are two-arity (TRequest, TResponse); double-check before registering.
- Keep pre- and post-processor classes in separate folders/namespaces.
When it happens
Trigger: Calling cfg.AddRequestPostProcessor(typeof(MyProcessor)) where MyProcessor implements IRequestPreProcessor<> (wrong arity/direction) or no processor interface; passing an open generic type into this closed API.
Common situations: Confusing pre- and post-processors; passing an open generic class (use AddOpenRequestPostProcessor); refactoring that removes the interface.
Related errors
- {openBehaviorType.Name} must implement {typeof(IRequestPostP
- {openBehaviorType.Name} must implement {typeof(IStreamPipeli
- {implementationType.Name} must implement {typeof(IRequestPre
- {openBehaviorType.Name} must implement {typeof(IRequestPrePr
- Error registering the generic type: {requestType.FullName}.
AI-assisted analysis of LuckyPennySoftware/MediatR@916ef1b3d6 (2026-08-13).
Data as JSON: /api/errors/5bb66363bb2cdb38.
Report an issue: GitHub.