{"record":{"id":"0132fa91b6211704","repo":"MassTransit/MassTransit","slug":"the-configurator-must-be-a-consumer-specification-0132fa","errorCode":null,"errorMessage":"The configurator must be a consumer specification","messagePattern":"The configurator must be a consumer specification","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/MassTransit/DependencyInjection/Configuration/MessageScopeConfigurationObserver.cs","lineNumber":43,"sourceCode":"            _setScopedConsumeContext = setScopedConsumeContext;\n\n            Connect(this);\n        }\n\n        public void MessageConfigured<TMessage>(IConsumePipeConfigurator configurator)\n            where TMessage : class\n        {\n            var scopeProvider = new ConsumeScopeProvider(_serviceProvider, _setScopedConsumeContext);\n            var scopeFilter = new ScopeMessageFilter<TMessage>(scopeProvider);\n            var specification = new FilterPipeSpecification<ConsumeContext<TMessage>>(scopeFilter);\n\n            configurator.AddPipeSpecification(specification);\n        }\n\n        public override void BatchConsumerConfigured<TConsumer, TMessage>(IConsumerMessageConfigurator<TConsumer, Batch<TMessage>> configurator)\n        {\n            if (!(configurator is IConsumerMessageSpecification<TConsumer, Batch<TMessage>> consumerSpecification))\n                throw new ArgumentException(\"The configurator must be a consumer specification\");\n\n            var scopeProvider = new ConsumeScopeProvider(_serviceProvider, _setScopedConsumeContext);\n            var scopeFilter = new ScopeMessageFilter<Batch<TMessage>>(scopeProvider);\n            var specification = new FilterPipeSpecification<ConsumeContext<Batch<TMessage>>>(scopeFilter);\n\n            consumerSpecification.AddPipeSpecification(specification);\n        }\n\n        public override void ActivityConfigured<TActivity, TArguments>(IExecuteActivityConfigurator<TActivity, TArguments> configurator, Uri compensateAddress)\n        {\n            var scopeProvider = new ExecuteActivityScopeProvider<TActivity, TArguments>(_serviceProvider, _setScopedConsumeContext);\n            var scopeFilter = new ScopeExecuteFilter<TActivity, TArguments>(scopeProvider);\n            var specification = new FilterPipeSpecification<ExecuteContext<TArguments>>(scopeFilter);\n\n            configurator.Arguments(x => x.AddPipeSpecification(specification));\n        }\n\n        public override void ExecuteActivityConfigured<TActivity, TArguments>(IExecuteActivityConfigurator<TActivity, TArguments> configurator)","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/MassTransit/MassTransit/blob/62ab339afa3bac2e9b3fe1769d0d35d7e44778e9/src/MassTransit/DependencyInjection/Configuration/MessageScopeConfigurationObserver.cs#L25-L61","documentation":"BatchConsumerConfigured on MessageScopeConfigurationObserver expects the configurator passed by the pipe to also implement IConsumerMessageSpecification<TConsumer, Batch<TMessage>> so scope filters can be added. This defensive cast failure indicates the observer was attached to a configurator type that does not implement the expected specification interface - an internal contract violation, normally caused by a custom configurator, a mismatched observer registration, or a MassTransit/container package version mismatch.","triggerScenarios":"Attaching MessageScopeConfigurationObserver (directly or via AddMassTransit scoped-consume wiring) while a custom or third-party IConsumerMessageConfigurator for Batch<TMessage> does not implement IConsumerMessageSpecification<TConsumer, Batch<TMessage>>; registering batch consumers with mismatched MassTransit.Abstractions/MassTransit versions.","commonSituations":"Mixed NuGet package versions (MassTransit vs MassTransit.Abstractions) during an upgrade; custom consumer configurators that violate the interface contract; manually adding the observer in an unusual configuration rather than via standard AddMassTransit.","solutions":["Align all MassTransit package versions (MassTransit and MassTransit.Abstractions) to the same release","Register the observer only via the standard AddMassTransit configuration path, not manually","Check any custom IConsumerMessageConfigurator implementations implement the matching IConsumerMessageSpecification interface","Report as a bug if it occurs with stock configurators on aligned versions"],"exampleFix":"// before\nobserver.BatchConsumerConfigured<TConsumer, TMessage>(customConfigurator); // customConfigurator lacks IConsumerMessageSpecification\n// after\nvar consumerSpecification = customConfigurator as IConsumerMessageSpecification<TConsumer, Batch<TMessage>>;\nif (consumerSpecification == null) throw new ArgumentException(\"Custom configurator must implement IConsumerMessageSpecification\");","handlingStrategy":"try-catch","validationCode":"var consumerSpecification = configurator as IConsumerMessageSpecification<TConsumer, Batch<TMessage>>;\nif (consumerSpecification == null) throw new InvalidOperationException(\"Attach MessageScopeConfigurationObserver only to standard MassTransit consumer configurators\");","typeGuard":"static bool IsConsumerMessageSpecification<TConsumer,TMessage>(IConsumerMessageConfigurator<TConsumer, Batch<TMessage>> c) => c is IConsumerMessageSpecification<TConsumer, Batch<TMessage>>;","tryCatchPattern":"try { observer.BatchConsumerConfigured<TConsumer, TMessage>(configurator); } catch (ArgumentException ex) when (ex.Message == \"The configurator must be a consumer specification\") { /* log; indicates version mismatch or custom configurator bug */ }","preventionTips":["Keep all MassTransit packages on the same version","Avoid custom IConsumerMessageConfigurator implementations for Batch<TMessage>","Attach observers via the standard AddMassTransit pipeline, not manually"],"tags":["dependency-injection","masstransit","batch-consumer","interface-cast"],"backgroundTag":"internal-invariant-violation","analyzedSha":"62ab339afa3bac2e9b3fe1769d0d35d7e44778e9","analyzedAt":"2026-09-13T22:47:47.593Z","contentChangedAt":"2026-09-13T22:47:47.593Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}