{"record":{"id":"04ffa79f61150829","repo":"HangfireIO/Hangfire","slug":"can-t-perform-a-background-job-with-a-null-job","errorCode":null,"errorMessage":"Can't perform a background job with a null job.","messagePattern":"Can't perform a background job with a null job\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Hangfire.Core/Server/CoreBackgroundJobPerformer.cs","lineNumber":55,"sourceCode":"\n        private readonly JobActivator _activator;\n        private readonly TaskScheduler _taskScheduler;\n\n        public CoreBackgroundJobPerformer([NotNull] JobActivator activator, [CanBeNull] TaskScheduler taskScheduler)\n        {\n            _activator = activator ?? throw new ArgumentNullException(nameof(activator));\n            _taskScheduler = taskScheduler;\n        }\n\n        public object Perform(PerformContext context)\n        {\n            using (var scope = _activator.BeginScope(context))\n            {\n                object instance = null;\n\n                if (context.BackgroundJob.Job == null)\n                {\n                    throw new InvalidOperationException(\"Can't perform a background job with a null job.\");\n                }\n                \n                if (!context.BackgroundJob.Job.Method.IsStatic)\n                {\n                    instance = scope.Resolve(context.BackgroundJob.Job.Type);\n\n                    if (instance == null)\n                    {\n                        throw new InvalidOperationException(\n                            $\"JobActivator returned NULL instance of the '{context.BackgroundJob.Job.Type}' type.\");\n                    }\n                }\n\n                var arguments = SubstituteArguments(context);\n                var result = InvokeMethod(context, instance, arguments);\n\n                return result;\n            }","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/Server/CoreBackgroundJobPerformer.cs#L37-L73","documentation":"Thrown by CoreBackgroundJobPerformer.Perform when the BackgroundJob.Job property is null at execution time. The performer needs a Job to know which method to invoke; a null Job means the background-job record in storage is incomplete or corrupt (no method/type serialized).","triggerScenarios":"A worker dequeues a background job whose serialized InvocationData did not yield a Job, or the BackgroundJob object was constructed without a Job. This is reached during actual job performance on the server.","commonSituations":"Corrupt job record in storage (missing Job fields). A custom enqueuer that created a background job without a proper method expression. Storage migration that lost payload. Race condition where a job was deleted but still being processed.","solutions":["Let the job fail and be moved to the Failed state; then delete it from storage to stop retries.","Investigate how the job was enqueued — ensure BackgroundJob.Enqueue/Job.FromExpression is used so the Job is serialized.","If using a custom storage, verify it round-trips the InvocationData/Job payload correctly."],"exampleFix":"// before — custom enqueuer omitted the method payload\n// (job stored without serialized Job)\n\n// after — enqueue through the standard client so Job is serialized\nBackgroundJob.Enqueue(() => Console.WriteLine(\"ok\"));","handlingStrategy":"try-catch","validationCode":"// Ensure jobs are always enqueued with a real method expression so Job is non-null\nif (job == null) throw new ArgumentNullException(nameof(job));\nBackgroundJob.Enqueue(() => job.Run());","typeGuard":null,"tryCatchPattern":"// Let the performer throw; the job moves to Failed state, then purge it\n// (no user-side try/catch — handle via dashboard or retry policy)","preventionTips":["Always enqueue via BackgroundJob.Enqueue(() => ...) or IBackgroundJobClient so the Job is serialized.","Avoid creating background-job records manually in storage.","Monitor the failed-jobs list and delete corrupt entries promptly."],"tags":["performer","storage-corruption","invalid-operation","server"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}