LuckyPennySoftware/MediatR · error · InvalidOperationException

The type "{openBehaviorType.Name}" must implement IPipelineB

Error message

The type "{openBehaviorType.Name}" must implement IPipelineBehavior<,> interface.

What it means

OpenBehavior's ValidatePipelineBehaviorType uses reflection to confirm the supplied Type implements the open-generic IPipelineBehavior<,> interface. If no implemented interface matches the IPipelineBehavior<,> generic definition, it throws InvalidOperationException so an invalid behavior never silently registers.

Source

Thrown at src/MediatR/Entities/OpenBehavior.cs:50

    /// </summary>
    public ServiceLifetime ServiceLifetime { get; }

    /// <summary>
    /// Validates whether the specified type implements the <see cref="IPipelineBehavior{TRequest, TResponse}"/> interface.
    /// </summary>
    /// <param name="openBehaviorType">The type to validate.</param>
    /// <exception cref="InvalidOperationException">Thrown if the type does not implement <see cref="IPipelineBehavior{TRequest, TResponse}"/>.</exception>
    /// <exception cref="ArgumentNullException">Thrown if <paramref name="openBehaviorType"/> is null.</exception>
    private static void ValidatePipelineBehaviorType(Type openBehaviorType)
    {
        if (openBehaviorType == null) throw new ArgumentNullException($"Open behavior type can not be null.");

        bool isPipelineBehavior = openBehaviorType.GetInterfaces()
            .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPipelineBehavior<,>));

        if (!isPipelineBehavior)
        {
            throw new InvalidOperationException($"The type \"{openBehaviorType.Name}\" must implement IPipelineBehavior<,> interface.");
        }
    }
}

View on GitHub (pinned to 916ef1b3d6)

Solutions

  1. Ensure the type implements IPipelineBehavior<TRequest, TResponse> (use AddStreamBehavior / IStreamPipelineBehavior for stream pipelines).
  2. If the type is closed (not open generic), use AddBehavior instead of AddOpenBehavior.
  3. Register via typeof(YourBehavior<,>) for open-generic or typeof(YourBehavior<TReq,TResp>) for closed.

Example fix

// before
// StreamBehavior<TReq,TResp> implements IStreamPipelineBehavior<,>, not IPipelineBehavior<,>
configuration.AddOpenBehavior(typeof(StreamBehavior<,>));
// after
configuration.AddOpenStreamBehavior(typeof(StreamBehavior<,>));
Defensive patterns

Strategy: validation

Validate before calling

bool isPipelineBehavior = openBehaviorType!.GetInterfaces()
    .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPipelineBehavior<,>));
if (!isPipelineBehavior)
    throw new InvalidOperationException($"{openBehaviorType.Name} is not an IPipelineBehavior<,>.");

Type guard

static bool IsOpenPipelineBehavior(Type t) =>
    t.IsGenericType && t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPipelineBehavior<,>));

Prevention

When it happens

Trigger: Constructing OpenBehavior with a Type that is not generic and/or does not close IPipelineBehavior<TRequest,TResponse> (e.g. a plain class, an interface implementor of a different contract, or a closed non-behavior class).

Common situations: Registering a request pre/post-processor or a stream pipeline behavior by mistake against AddOpenBehavior; passing an open generic that closes IStreamPipelineBehavior<,> instead of IPipelineBehavior<,>; passing a concrete non-generic class.

Related errors


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