HangfireIO/Hangfire · error · ArgumentNullException

stateMachine

Error message

stateMachine

What it means

Thrown by the CoreBackgroundJobFactory constructor when stateMachine is null. CoreBackgroundJobFactory is the inner factory that actually persists a job and applies its initial state via IStateMachine.ApplyState. The state machine is required to transition a newly created job into its EnqueuedState/ScheduledState etc. Because CoreBackgroundJobFactory is internal and normally constructed by BackgroundJobFactory (which wires a StateMachine(filterProvider)), a null here indicates a broken custom factory or reflection-based instantiation.

Source

Thrown at src/Hangfire.Core/Client/CoreBackgroundJobFactory.cs:38

using System.Threading;
using Hangfire.Annotations;
using Hangfire.Common;
using Hangfire.Logging;
using Hangfire.States;
using Hangfire.Storage;

namespace Hangfire.Client
{
    internal sealed class CoreBackgroundJobFactory : IBackgroundJobFactory
    {
        private readonly ILog _logger = LogProvider.GetLogger(typeof(CoreBackgroundJobFactory));
        private readonly object _syncRoot = new object();
        private int _retryAttempts;
        private Func<int, TimeSpan> _retryDelayFunc;

        public CoreBackgroundJobFactory([NotNull] IStateMachine stateMachine)
        {
            StateMachine = stateMachine ?? throw new ArgumentNullException(nameof(stateMachine));
            RetryAttempts = 0;
            RetryDelayFunc = GetRetryDelay;
        }

        public IStateMachine StateMachine { get; }

        public int RetryAttempts
        {
            get { lock (_syncRoot) { return _retryAttempts; } }
            set { lock (_syncRoot) { _retryAttempts = value; } }
        }

        public Func<int, TimeSpan> RetryDelayFunc
        {
            get { lock (_syncRoot) { return _retryDelayFunc; } }
            set { lock (_syncRoot) { _retryDelayFunc = value; } }
        }

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Use BackgroundJobFactory (the public decorator) which constructs CoreBackgroundJobFactory with a properly wired StateMachine(filterProvider).
  2. When constructing manually, pass a valid IStateMachine such as new StateMachine(JobFilterProviders.Providers).
  3. Register IStateMachine in your DI container if resolving CoreBackgroundJobFactory directly.

Example fix

// before
var factory = new CoreBackgroundJobFactory(null);

// after
var stateMachine = new StateMachine(JobFilterProviders.Providers);
var factory = new CoreBackgroundJobFactory(stateMachine);
Defensive patterns

Strategy: validation

Validate before calling

var stateMachine = providedStateMachine ?? new StateMachine(JobFilterProviders.Providers);
var factory = new CoreBackgroundJobFactory(stateMachine);

Type guard

public static bool IsValidStateMachine(IStateMachine sm)
    => sm != null;

Prevention

When it happens

Trigger: Reflectively instantiating CoreBackgroundJobFactory with a null IStateMachine; a custom IBackgroundJobFactory that internally builds CoreBackgroundJobFactory incorrectly; DI containers that fail to resolve IStateMachine.

Common situations: Custom factory wrappers that bypass the BackgroundJobFactory constructor; test harnesses that new-up CoreBackgroundJobFactory without a StateMachine; advanced scenarios replacing the state-machine pipeline.

Related errors


AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13). Data as JSON: /api/errors/2479f585bb7967b3. Report an issue: GitHub.