LuckyPennySoftware/MediatR · error · InvalidOperationException
{openBehaviorType.Name} must implement {typeof(IRequestPrePr
Error message
{openBehaviorType.Name} must implement {typeof(IRequestPreProcessor<>).FullName} What it means
Thrown by AddOpenRequestPreProcessor after the generic check passes: the type is generic but none of its implemented generic interfaces equal IRequestPreProcessor<>. MediatR filters GetInterfaces() to generic definitions and requires at least one match to register.
Source
Thrown at src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs:422
/// <summary>
/// Registers an open request pre processor type against the <see cref="IRequestPreProcessor{TRequest}"/> open generic interface type
/// </summary>
/// <param name="openBehaviorType">An open generic request pre processor type</param>
/// <param name="serviceLifetime">Optional service lifetime, defaults to <see cref="ServiceLifetime.Transient"/>.</param>
/// <returns>This</returns>
public MediatRServiceConfiguration AddOpenRequestPreProcessor(Type openBehaviorType, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
{
if (!openBehaviorType.IsGenericType)
{
throw new InvalidOperationException($"{openBehaviorType.Name} must be generic");
}
var implementedGenericInterfaces = openBehaviorType.GetInterfaces().Where(i => i.IsGenericType).Select(i => i.GetGenericTypeDefinition());
var implementedOpenBehaviorInterfaces = new HashSet<Type>(implementedGenericInterfaces.Where(i => i == typeof(IRequestPreProcessor<>)));
if (implementedOpenBehaviorInterfaces.Count == 0)
{
throw new InvalidOperationException($"{openBehaviorType.Name} must implement {typeof(IRequestPreProcessor<>).FullName}");
}
foreach (var openBehaviorInterface in implementedOpenBehaviorInterfaces)
{
RequestPreProcessorsToRegister.Add(new ServiceDescriptor(openBehaviorInterface, openBehaviorType, serviceLifetime));
}
return this;
}
/// <summary>
/// Register a closed request post processor type
/// </summary>
/// <typeparam name="TServiceType">Closed request post processor interface type</typeparam>
/// <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<TServiceType, TImplementationType>(ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
View on GitHub (pinned to 916ef1b3d6)
Solutions
- Implement the open interface on the generic class: class MyProcessor<TRequest> : IRequestPreProcessor<TRequest>.
- If the type actually implements IRequestPostProcessor<,> or IPipelineBehavior<,>, move the registration to AddOpenRequestPostProcessor / AddOpenBehavior respectively.
- Confirm the open generic declares the interface with the matching open type parameter, not a concrete one.
Example fix
// before
public class MyProcessor<TRequest, TResponse>
: IRequestPostProcessor<TRequest, TResponse> { ... }
cfg.AddOpenRequestPreProcessor(typeof(MyProcessor<,>));
// after
cfg.AddOpenRequestPostProcessor(typeof(MyProcessor<,>)); Defensive patterns
Strategy: validation
Validate before calling
static bool ImplementsOpenPreProcessor(Type t) =>
t.IsGenericType &&
t.GetInterfaces()
.Where(i => i.IsGenericType)
.Select(i => i.GetGenericTypeDefinition())
.Any(i => i == typeof(IRequestPreProcessor<>));
if (ImplementsOpenPreProcessor(typeof(MyProcessor<>)))
cfg.AddOpenRequestPreProcessor(typeof(MyProcessor<>)); Type guard
static bool IsOpenRequestPreProcessor(Type t) =>
t.IsGenericType &&
t.GetInterfaces()
.Where(i => i.IsGenericType)
.Select(i => i.GetGenericTypeDefinition())
.Contains(typeof(IRequestPreProcessor<>)); Prevention
- Confirm the interface arity matches the API (pre-processor = single arity).
- Use a unit test that registers each open processor against the configuration.
When it happens
Trigger: Registering typeof(MyGenericBehavior<>) where the class is generic but implements IRequestPostProcessor<,>, IPipelineBehavior<,>, or no processor interface.
Common situations: Open generic class that implements a different MediatR interface; renamed interface; wrong arity chosen (pre-processor is single-arity IRequestPreProcessor<TRequest>).
Related errors
- {openBehaviorType.Name} must implement {typeof(IStreamPipeli
- {implementationType.Name} must implement {typeof(IRequestPre
- {openBehaviorType.Name} must implement {typeof(IRequestPostP
- Error registering the generic type: {requestType.FullName}.
- Error registering the generic type: {requestType.FullName}.
AI-assisted analysis of LuckyPennySoftware/MediatR@916ef1b3d6 (2026-08-13).
Data as JSON: /api/errors/5034f125cc948539.
Report an issue: GitHub.