LuckyPennySoftware/MediatR · error · InvalidOperationException

{openBehaviorType.Name} must implement {typeof(IRequestPostP

Error message

{openBehaviorType.Name} must implement {typeof(IRequestPostProcessor<,>).FullName}

What it means

Thrown by AddOpenRequestPostProcessor after the generic check passes: the type is generic but none of its generic interface definitions equals IRequestPostProcessor<,>. MediatR needs that interface to build the ServiceDescriptor.

Source

Thrown at src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs:506

    /// <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)
        {
            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(IRequestPostProcessor<,>)));

        if (implementedOpenBehaviorInterfaces.Count == 0)
        {
            throw new InvalidOperationException($"{openBehaviorType.Name} must implement {typeof(IRequestPostProcessor<,>).FullName}");
        }

        foreach (var openBehaviorInterface in implementedOpenBehaviorInterfaces)
        {
            RequestPostProcessorsToRegister.Add(new ServiceDescriptor(openBehaviorInterface, openBehaviorType, serviceLifetime));
        }

        return this;
    }


}

View on GitHub (pinned to 916ef1b3d6)

Solutions

  1. Implement the open two-arity interface: class MyProcessor<TRequest,TResponse> : IRequestPostProcessor<TRequest,TResponse>.
  2. If the type implements IRequestPreProcessor<>, register it with AddOpenRequestPreProcessor instead.
  3. If it implements IPipelineBehavior<,>, use AddOpenBehavior.

Example fix

// before
public class MyProcessor<TRequest> : IRequestPreProcessor<TRequest> { ... }
cfg.AddOpenRequestPostProcessor(typeof(MyProcessor<>));

// after
cfg.AddOpenRequestPreProcessor(typeof(MyProcessor<>));
Defensive patterns

Strategy: validation

Validate before calling

static bool ImplementsOpenPostProcessor(Type t) =>
    t.IsGenericType &&
    t.GetInterfaces()
        .Where(i => i.IsGenericType)
        .Select(i => i.GetGenericTypeDefinition())
        .Any(i => i == typeof(IRequestPostProcessor<,>));

if (ImplementsOpenPostProcessor(typeof(MyProcessor<,>)))
    cfg.AddOpenRequestPostProcessor(typeof(MyProcessor<,>));

Type guard

static bool IsOpenRequestPostProcessor(Type t) =>
    t.IsGenericType &&
    t.GetInterfaces()
        .Where(i => i.IsGenericType)
        .Select(i => i.GetGenericTypeDefinition())
        .Contains(typeof(IRequestPostProcessor<,>));

Prevention

When it happens

Trigger: Registering typeof(MyGeneric<>) that is generic but implements IRequestPreProcessor<> (single arity), IPipelineBehavior<,>, or no processor interface.

Common situations: Open generic class wired to the wrong MediatR interface; arity mismatch; rename/refactor that drops the interface.

Related errors


AI-assisted analysis of LuckyPennySoftware/MediatR@916ef1b3d6 (2026-08-13). Data as JSON: /api/errors/edfdc417252fd6dd. Report an issue: GitHub.