{"record":{"id":"6a332f57c7ea1601","repo":"LuckyPennySoftware/MediatR","slug":"openbehaviortype-name-must-implement-typeof-ipi","errorCode":null,"errorMessage":"{openBehaviorType.Name} must implement {typeof(IPipelineBehavior<,>).FullName}","messagePattern":"(.+?) must implement (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs","lineNumber":220,"sourceCode":"    /// <summary>\r\n    /// Registers an open behavior type against the <see cref=\"IPipelineBehavior{TRequest,TResponse}\"/> open generic interface type\r\n    /// </summary>\r\n    /// <param name=\"openBehaviorType\">An open generic behavior type</param>\r\n    /// <param name=\"serviceLifetime\">Optional service lifetime, defaults to <see cref=\"ServiceLifetime.Transient\"/>.</param>\r\n    /// <returns>This</returns>\r\n    public MediatRServiceConfiguration AddOpenBehavior(Type openBehaviorType, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)\r\n    {\r\n        if (!openBehaviorType.IsGenericType)\r\n        {\r\n            throw new InvalidOperationException($\"{openBehaviorType.Name} must be generic\");\r\n        }\r\n\r\n        var implementedGenericInterfaces = openBehaviorType.GetInterfaces().Where(i => i.IsGenericType).Select(i => i.GetGenericTypeDefinition());\r\n        var implementedOpenBehaviorInterfaces = new HashSet<Type>(implementedGenericInterfaces.Where(i => i == typeof(IPipelineBehavior<,>)));\r\n\r\n        if (implementedOpenBehaviorInterfaces.Count == 0)\r\n        {\r\n            throw new InvalidOperationException($\"{openBehaviorType.Name} must implement {typeof(IPipelineBehavior<,>).FullName}\");\r\n        }\r\n\r\n        foreach (var openBehaviorInterface in implementedOpenBehaviorInterfaces)\r\n        {\r\n            BehaviorsToRegister.Add(new ServiceDescriptor(openBehaviorInterface, openBehaviorType, serviceLifetime));\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /// <summary>\r\n    /// Registers multiple open behavior types against the <see cref=\"IPipelineBehavior{TRequest,TResponse}\"/> open generic interface type\r\n    /// </summary>\r\n    /// <param name=\"openBehaviorTypes\">An open generic behavior type list includes multiple open generic behavior types.</param>\r\n    /// <param name=\"serviceLifetime\">Optional service lifetime, defaults to <see cref=\"ServiceLifetime.Transient\"/>.</param>\r\n    /// <returns>This</returns>\r\n    public MediatRServiceConfiguration AddOpenBehaviors(IEnumerable<Type> openBehaviorTypes, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)\r\n    {\r","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/LuckyPennySoftware/MediatR/blob/916ef1b3d68ccdc96db8f914eaf1b32fc7db52c5/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs#L202-L238","documentation":"After confirming the type is generic, AddOpenBehavior reflects over its interfaces for the open-generic IPipelineBehavior<,> definition. If none matches, it throws InvalidOperationException so an open generic that closes a different contract cannot be registered as a request pipeline behavior.","triggerScenarios":"Passing an open-generic type to AddOpenBehavior that implements IStreamPipelineBehavior<,>, IRequestPreProcessor<>, IRequestPostProcessor<,>, or no behavior contract at all.","commonSituations":"Registering an open stream pipeline behavior through AddOpenBehavior instead of AddOpenStreamBehavior; registering a generic pre/post-processor through the wrong method.","solutions":["Confirm the type implements IPipelineBehavior<TRequest, TResponse> (open form).","For stream pipelines use AddOpenStreamBehavior(typeof(Foo<,>)).","For pre/post-processors use the corresponding AddOpen* methods."],"exampleFix":"// before\n// StreamLogging<,> implements IStreamPipelineBehavior<,>\nconfiguration.AddOpenBehavior(typeof(StreamLogging<,>));\n// after\nconfiguration.AddOpenStreamBehavior(typeof(StreamLogging<,>));","handlingStrategy":"validation","validationCode":"bool closes = openBehaviorType.GetInterfaces()\n    .Where(i => i.IsGenericType).Select(i => i.GetGenericTypeDefinition())\n    .Any(i => i == typeof(IPipelineBehavior<,>));\nif (!closes) throw new InvalidOperationException($\"{openBehaviorType.Name} does not close IPipelineBehavior<,>.\");","typeGuard":"static bool IsOpenPipelineBehavior(Type t) =>\n    t.IsGenericType && t.GetInterfaces().Where(i => i.IsGenericType)\n        .Select(i => i.GetGenericTypeDefinition()).Any(i => i == typeof(IPipelineBehavior<,>));","tryCatchPattern":null,"preventionTips":["Register stream pipelines via AddOpenStreamBehavior, not AddOpenBehavior.","Confirm the open generic closes IPipelineBehavior<,> before registering."],"tags":["pipeline-behavior","open-behavior","registration","di","type-validation","reflection"],"backgroundTag":null,"analyzedSha":"916ef1b3d68ccdc96db8f914eaf1b32fc7db52c5","analyzedAt":"2026-08-13T17:57:04.476Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}