{"record":{"id":"cd0b4baad2d3cfdc","repo":"MassTransit/MassTransit","slug":"consumer-type-typecache-tconsumer-shortname-is-not-a","errorCode":null,"errorMessage":"Consumer type {TypeCache<TConsumer>.ShortName} is not a consumer of job type {TypeCache<TJob>.ShortName}","messagePattern":"Consumer type (.+?) is not a consumer of job type (.+?)","errorType":"exception","errorClass":"ConsumerMessageException","httpStatus":null,"severity":"error","filePath":"src/MassTransit/Middleware/JobConsumerMessageFilter.cs","lineNumber":38,"sourceCode":"        {\n            _retryPolicy = retryPolicy;\n        }\n\n        public void Probe(ProbeContext context)\n        {\n            var scope = context.CreateScope(\"consume\");\n            scope.Add(\"method\", $\"Consume(ConsumeContext<{TypeCache<TJob>.ShortName}> context)\");\n        }\n\n        public Task Send(ConsumerConsumeContext<TConsumer, TJob> context,\n            IPipe<ConsumerConsumeContext<TConsumer, TJob>> next)\n        {\n            if (context.Consumer is IJobConsumer<TJob> messageConsumer)\n                return RunJob(context, messageConsumer);\n\n            var message = $\"Consumer type {TypeCache<TConsumer>.ShortName} is not a consumer of job type {TypeCache<TJob>.ShortName}\";\n\n            throw new ConsumerMessageException(message);\n        }\n\n        async Task RunJob(PipeContext context, IJobConsumer<TJob> jobConsumer)\n        {\n            var jobContext = context.GetPayload<JobContext<TJob>>();\n            var notifyJobContext = context.GetPayload<INotifyJobContext>();\n\n            RetryPolicyContext<JobContext<TJob>> policyContext = _retryPolicy.CreatePolicyContext(jobContext);\n\n            try\n            {\n                await notifyJobContext.NotifyStarted().ConfigureAwait(false);\n\n                await jobConsumer.Run(jobContext).ConfigureAwait(false);\n\n                await notifyJobContext.NotifyCompleted().ConfigureAwait(false);\n            }\n            catch (OperationCanceledException exception) when (jobContext.CancellationToken == exception.CancellationToken)","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/MassTransit/MassTransit/blob/62ab339afa3bac2e9b3fe1769d0d35d7e44778e9/src/MassTransit/Middleware/JobConsumerMessageFilter.cs#L20-L56","documentation":"JobConsumerMessageFilter.Send checks that the consumer instance implements IJobConsumer<TJob>; if it does not, it throws ConsumerMessageException stating the consumer type is not a job consumer of the given job type. MassTransit built the pipeline expecting a matching job consumer contract, so a mismatch is a configuration/registration error.","triggerScenarios":"Registering a consumer type on a job endpoint where the class does not implement IJobConsumer<TJob>, or generic type parameters got mismatched (TConsumer vs TJob do not line up with the class's interfaces).","commonSituations":"AddJobConsumer pointing at a class that only implements IConsumer<T>; renaming TJob without updating the consumer class; copy-pasting a job consumer and forgetting the interface.","solutions":["Make the consumer class implement IJobConsumer<TJob> for the job type on the endpoint","Register with AddJobConsumer<TConsumer>() instead of generic AddConsumer so types are matched correctly","Verify the TJob type parameter matches the job contract the endpoint is configured for"],"exampleFix":"// before\npublic class MyJobConsumer : IConsumer<RunJob> { ... }\n// after\npublic class MyJobConsumer : IJobConsumer<RunJob> { ... }","handlingStrategy":"validation","validationCode":"if (consumer is not IJobConsumer<TJob>)\n    throw new InvalidOperationException($\"{typeof(TConsumer).Name} must implement IJobConsumer<{typeof(TJob).Name}>\");","typeGuard":"bool IsJobConsumer<TJb>(object c) => c is IJobConsumer<TJb>;","tryCatchPattern":"try\n{\n    await pipeline.Send(context);\n}\ncatch (ConsumerMessageException ex)\n{\n    // registration error: consumer lacks IJobConsumer<TJob>\n    logger.LogError(ex, \"Job consumer registration mismatch\");\n}","preventionTips":["Implement IJobConsumer<TJob> on all job endpoint consumers","Use AddJobConsumer<T>() for registration","Keep TJob type parameters aligned with the job contract"],"tags":["masstransit","job-consumer","type-mismatch","configuration"],"backgroundTag":"type-mismatch","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"}