{"record":{"id":"5034f125cc948539","repo":"LuckyPennySoftware/MediatR","slug":"openbehaviortype-name-must-implement-typeof-ire","errorCode":null,"errorMessage":"{openBehaviorType.Name} must implement {typeof(IRequestPreProcessor<>).FullName}","messagePattern":"(.+?) must implement (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs","lineNumber":422,"sourceCode":"    /// <summary>\r\n    /// Registers an open request pre processor type against the <see cref=\"IRequestPreProcessor{TRequest}\"/> open generic interface type\r\n    /// </summary>\r\n    /// <param name=\"openBehaviorType\">An open generic request pre processor 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 AddOpenRequestPreProcessor(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(IRequestPreProcessor<>)));\r\n\r\n        if (implementedOpenBehaviorInterfaces.Count == 0)\r\n        {\r\n            throw new InvalidOperationException($\"{openBehaviorType.Name} must implement {typeof(IRequestPreProcessor<>).FullName}\");\r\n        }\r\n\r\n        foreach (var openBehaviorInterface in implementedOpenBehaviorInterfaces)\r\n        {\r\n            RequestPreProcessorsToRegister.Add(new ServiceDescriptor(openBehaviorInterface, openBehaviorType, serviceLifetime));\r\n        }\r\n\r\n        return this;\r\n    }\r\n    \r\n    /// <summary>\r\n    /// Register a closed request post processor type\r\n    /// </summary>\r\n    /// <typeparam name=\"TServiceType\">Closed request post processor interface type</typeparam>\r\n    /// <typeparam name=\"TImplementationType\">Closed request post processor implementation type</typeparam>\r\n    /// <param name=\"serviceLifetime\">Optional service lifetime, defaults to <see cref=\"ServiceLifetime.Transient\"/>.</param>\r\n    /// <returns>This</returns>\r\n    public MediatRServiceConfiguration AddRequestPostProcessor<TServiceType, TImplementationType>(ServiceLifetime serviceLifetime = ServiceLifetime.Transient)\r","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/LuckyPennySoftware/MediatR/blob/916ef1b3d68ccdc96db8f914eaf1b32fc7db52c5/src/MediatR/MicrosoftExtensionsDI/MediatrServiceConfiguration.cs#L404-L440","documentation":"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.","triggerScenarios":"Registering typeof(MyGenericBehavior<>) where the class is generic but implements IRequestPostProcessor<,>, IPipelineBehavior<,>, or no processor interface.","commonSituations":"Open generic class that implements a different MediatR interface; renamed interface; wrong arity chosen (pre-processor is single-arity IRequestPreProcessor<TRequest>).","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."],"exampleFix":"// before\npublic class MyProcessor<TRequest, TResponse>\n    : IRequestPostProcessor<TRequest, TResponse> { ... }\ncfg.AddOpenRequestPreProcessor(typeof(MyProcessor<,>));\n\n// after\ncfg.AddOpenRequestPostProcessor(typeof(MyProcessor<,>));","handlingStrategy":"validation","validationCode":"static bool ImplementsOpenPreProcessor(Type t) =>\n    t.IsGenericType &&\n    t.GetInterfaces()\n        .Where(i => i.IsGenericType)\n        .Select(i => i.GetGenericTypeDefinition())\n        .Any(i => i == typeof(IRequestPreProcessor<>));\n\nif (ImplementsOpenPreProcessor(typeof(MyProcessor<>)))\n    cfg.AddOpenRequestPreProcessor(typeof(MyProcessor<>));","typeGuard":"static bool IsOpenRequestPreProcessor(Type t) =>\n    t.IsGenericType &&\n    t.GetInterfaces()\n        .Where(i => i.IsGenericType)\n        .Select(i => i.GetGenericTypeDefinition())\n        .Contains(typeof(IRequestPreProcessor<>));","tryCatchPattern":null,"preventionTips":["Confirm the interface arity matches the API (pre-processor = single arity).","Use a unit test that registers each open processor against the configuration."],"tags":["di-registration","pre-processor","open-generic","configuration"],"backgroundTag":null,"analyzedSha":"916ef1b3d68ccdc96db8f914eaf1b32fc7db52c5","analyzedAt":"2026-08-13T17:57:04.476Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}