HangfireIO/Hangfire · error · ArgumentNullException
execution
Error message
execution
What it means
Thrown as ArgumentNullException by the BackgroundDispatcher constructor when the 'execution' IBackgroundExecution argument is null. The execution object owns the work queue and scheduling that the dispatcher's threads consume; a null execution leaves the dispatch loop with nothing to run, so the constructor rejects it via '?? throw' at line 47.
Source
Thrown at src/Hangfire.Core/Processing/BackgroundDispatcher.cs:47
{
internal sealed class BackgroundDispatcher : IBackgroundDispatcher
{
private readonly ILog _logger = LogProvider.GetLogger(typeof(BackgroundDispatcher));
private readonly CountdownEvent _stopped;
private readonly IBackgroundExecution _execution;
private readonly Action<Guid, object> _action;
private readonly object _state;
public BackgroundDispatcher(
[NotNull] IBackgroundExecution execution,
[NotNull] Action<Guid, object> action,
[CanBeNull] object state,
[NotNull] Func<ThreadStart, IEnumerable<Thread>> threadFactory)
{
if (threadFactory == null) throw new ArgumentNullException(nameof(threadFactory));
_execution = execution ?? throw new ArgumentNullException(nameof(execution));
_action = action ?? throw new ArgumentNullException(nameof(action));
_state = state;
#if !NETSTANDARD1_3
AppDomainUnloadMonitor.EnsureInitialized();
#endif
var threads = threadFactory(DispatchLoop)?.ToArray();
if (threads == null || threads.Length == 0)
{
throw new ArgumentException("At least one unstarted thread should be created.", nameof(threadFactory));
}
if (threads.Any(static thread => thread == null || (thread.ThreadState & ThreadState.Unstarted) == 0))
{
throw new ArgumentException("All the threads should be non-null and in the ThreadState.Unstarted state.", nameof(threadFactory));
}View on GitHub (pinned to c236dd0f93)
Solutions
- If you maintain a custom processing server, ensure a non-null IBackgroundExecution is created and passed (the framework normally builds one for the configured worker count).
- Use the public BackgroundJobServer API, which constructs the execution and dispatcher internally.
- In tests, provide a real or mock IBackgroundExecution rather than null.
Example fix
// before var d = new BackgroundDispatcher(null, action, state, factory); // after var execution = new BackgroundExecution(serverOptions, state); var d = new BackgroundDispatcher(execution, action, state, factory);
Defensive patterns
Strategy: validation
Validate before calling
if (execution == null) throw new ArgumentNullException(nameof(execution)); var execution = new BackgroundExecution(serverOptions, state);
Prevention
- Use the public BackgroundJobServer API which constructs the execution internally.
- In custom servers/tests, provide a real or mock IBackgroundExecution, never null.
When it happens
Trigger: Constructing a BackgroundDispatcher with a null IBackgroundExecution. BackgroundDispatcher is internal and is normally built by the processing server with a configured execution; a null execution only arises from custom processing-server code or tests that build the dispatcher manually.
Common situations: A custom processing server that instantiates BackgroundDispatcher without an IBackgroundExecution; a test stub that omits the execution; a refactor where the execution was replaced by null. Standard BackgroundJobServer users never pass this argument.
Related errors
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/0c7843e21a266175.
Report an issue: GitHub.