HangfireIO/Hangfire · error · ArgumentNullException
connectionFactory
Error message
connectionFactory
What it means
The SqlServerStorage constructor received a null connectionFactory argument (a Func<DbConnection>). This is a standard ArgumentNullException guard at the top of the (Func<DbConnection>, SqlServerStorageOptions) constructor.
Source
Thrown at src/Hangfire.SqlServer/SqlServerStorage.cs:143
/// <summary>
/// Initializes a new instance of the <see cref="SqlServerStorage"/> class with
/// a connection factory <see cref="Func{DbConnection}"/> class that will be invoked
/// to create new database connections for querying the data.
/// </summary>
public SqlServerStorage([NotNull] Func<DbConnection> connectionFactory)
: this(connectionFactory, new SqlServerStorageOptions())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SqlServerStorage"/> class with
/// a connection factory <see cref="Func{DbConnection}"/> class that will be invoked
/// to create new database connections for querying the data.
/// </summary>
public SqlServerStorage([NotNull] Func<DbConnection> connectionFactory, [NotNull] SqlServerStorageOptions options)
{
if (connectionFactory == null) throw new ArgumentNullException(nameof(connectionFactory));
if (options == null) throw new ArgumentNullException(nameof(options));
_connectionFactory = connectionFactory;
_options = options;
Initialize();
}
public virtual PersistentJobQueueProviderCollection QueueProviders { get; private set; }
public override bool LinearizableReads => true;
internal string SchemaName => _escapedSchemaName;
internal int? CommandTimeout => _options.CommandTimeout.HasValue ? (int)_options.CommandTimeout.Value.TotalSeconds : (int?)null;
internal int? CommandBatchMaxTimeout => _options.CommandBatchMaxTimeout.HasValue ? (int)_options.CommandBatchMaxTimeout.Value.TotalSeconds : (int?)null;
internal TimeSpan? SlidingInvisibilityTimeout => _options.SlidingInvisibilityTimeout;
internal SqlServerStorageOptions Options => _options;
internal SqlServerHeartbeatProcess HeartbeatProcess => _heartbeatProcess;View on GitHub (pinned to c236dd0f93)
Solutions
- Provide a non-null Func<DbConnection> that returns a new, unopened DbConnection each invocation.
- If the factory comes from DI, ensure it is registered and resolvable.
- Validate with a null check before construction.
Example fix
// before Func<DbConnection> factory = null; // not initialized var storage = new SqlServerStorage(factory, options); // after Func<DbConnection> factory = () => new SqlConnection(connectionString); var storage = new SqlServerStorage(factory, options);
Defensive patterns
Strategy: validation
Validate before calling
Func<DbConnection> connectionFactory = /* assignment */;
if (connectionFactory == null)
throw new InvalidOperationException("connectionFactory delegate must be provided.");
var storage = new SqlServerStorage(connectionFactory, options); Type guard
static bool IsValidFactory(Func<DbConnection> factory) => factory != null;
Prevention
- Always initialize the factory delegate before passing it to SqlServerStorage.
- Register the factory in DI if using dependency injection.
- Ensure the factory returns a fresh, unopened DbConnection each invocation.
When it happens
Trigger: Passing null to new SqlServerStorage(connectionFactory, options); a factory variable that was never assigned.
Common situations: DI misconfiguration where the factory delegate resolves to null; refactoring that removes the factory assignment; conditional code paths that skip factory initialization.
Related errors
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/7bee91a1c21396ae.
Report an issue: GitHub.