{"record":{"id":"7dc6203691e6474b","repo":"HangfireIO/Hangfire","slug":"value-7dc620","errorCode":null,"errorMessage":"value","messagePattern":"value","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Hangfire.SqlServer/SqlServerStorageOptions.cs","lineNumber":202,"sourceCode":"        /// <summary>\n        /// Gets or sets whether to enable experimental feature of transactional acknowledge of completed\n        /// background jobs. In this case there will be less requests sent to SQL Server and better handling\n        /// of data loss when asynchronous replication is used. But additional blocking on the JobQueue table\n        /// is expected, since transaction commit requires an explicit Commit request to be sent. \n        /// </summary>\n        public bool UseTransactionalAcknowledge { get; set; }\n\n        /// <summary>\n        /// Gets or sets the <see cref=\"DbProviderFactory\"/> for creating <c>SqlConnection</c> instances.\n        /// Defaults to either <c>System.Data.SqlClient.SqlClientFactory.Instance</c> or\n        /// <c>Microsoft.Data.SqlClient.SqlClientFactory</c> depending on which package reference exists\n        /// on the consuming project.\n        /// </summary>\n        public DbProviderFactory SqlClientFactory\n        {\n            get => _sqlClientFactory ?? throw new InvalidOperationException(\"Please add a NuGet package reference to either 'Microsoft.Data.SqlClient' or 'System.Data.SqlClient' in your application project. \" +\n                                                                            \"Hangfire.SqlServer supports both providers but let the consumer decide which one should be used.\");\n            set => _sqlClientFactory = value ?? throw new ArgumentNullException(nameof(value));\n        }\n\n        /// <summary>\n        /// Gets or sets whether to try automatically query for the current schema on application start\n        /// and enable <see cref=\"UseIgnoreDupKeyOption\"/>, <see cref=\"DeleteExpiredBatchSize\"/> and\n        /// <see cref=\"DisableGlobalLocks\"/> options depending on the current schema version. When storage\n        /// is inaccessible on startup, default values will be used for those options.\n        /// </summary>\n        public bool TryAutoDetectSchemaDependentOptions { get; set; }\n\n        /// <summary>\n        /// Gets or sets a default queue provider that will be used when no special provider was\n        /// registered for a particular queue.\n        /// </summary>\n        public IPersistentJobQueueProvider DefaultQueueProvider { get; set; }\n\n#if FEATURE_TRANSACTIONSCOPE\n        /// <summary>","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.SqlServer/SqlServerStorageOptions.cs#L184-L220","documentation":"ArgumentNullException thrown by the setter of the SqlServerStorageOptions.SqlClientFactory property (SqlServerStorageOptions.cs:202) when it is assigned null. The backing field _sqlClientFactory holds the DbProviderFactory used to create SqlConnection instances; assigning null is explicitly rejected. Note the getter is a separate failure mode: it throws InvalidOperationException if no default client factory was detected, but this particular error is the setter rejecting a null assignment.","triggerScenarios":"Executing `options.SqlClientFactory = null;` on a SqlServerStorageOptions instance. This happens with a direct null assignment, a conditional expression that evaluates to null (e.g. `options.SqlClientFactory = provider ?? null;`), or a reset routine that clears the provider.","commonSituations":"Attempt to 'reset' the SQL client provider at runtime; a provider-selection block whose fallback branch is null; DI/configuration binding that maps a missing setting to null; test teardown that nulls the factory.","solutions":["Do not assign null; if you want the default behavior, leave the property untouched (the constructor already calls GetDefaultSqlClientFactory()).","Assign a concrete factory: Microsoft.Data.SqlClient.SqlClientFactory.Instance or System.Data.SqlClient.SqlClientFactory.Instance.","Create a fresh SqlServerStorageOptions instance instead of resetting the factory on an existing one.","Fix the conditional logic so the branch never yields null, e.g. only assign when the provider value is non-null."],"exampleFix":"// before\noptions.SqlClientFactory = GetCurrentProvider(); // returns null in some path\n// after\nvar factory = GetCurrentProvider();\nif (factory != null) options.SqlClientFactory = factory;\n// or, to set explicitly:\noptions.SqlClientFactory = Microsoft.Data.SqlClient.SqlClientFactory.Instance;","handlingStrategy":"validation","validationCode":"var factory = ResolveSqlClientFactory();\nif (factory != null)\n{\n    options.SqlClientFactory = factory;\n}\n// never assign null; leave default if no explicit provider is chosen","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never assign null to SqlClientFactory; leave the constructor's default if unsure.","Resolve the provider once at startup and assign a concrete factory instance (Microsoft.Data.SqlClient.SqlClientFactory.Instance or System.Data.SqlClient.SqlClientFactory.Instance).","Ensure configuration-binding/DI maps missing settings to a real factory, not null.","To 'reset', create a new SqlServerStorageOptions rather than nulling the property."],"tags":["configuration","null-argument","sqlclient","argumentnullexception"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}