{"record":{"id":"c32c72aadd69e4fd","repo":"dotnet/orleans","slug":"invalid-nameof-adonetclusteringsilooptions-valu","errorCode":null,"errorMessage":"Invalid {nameof(AdoNetClusteringSiloOptions)} values for {nameof(AdoNetClusteringTable)}. {nameof(options.Invariant)} is required.","messagePattern":"Invalid (.+?) values for (.+?)\\. (.+?) is required\\.","errorType":"validation","errorClass":"OrleansConfigurationException","httpStatus":null,"severity":"error","filePath":"src/AdoNet/Orleans.Clustering.AdoNet/Options/AdoNetReminderTableOptionsValidator.cs","lineNumber":24,"sourceCode":"{\n    /// <summary>\n    /// Validates <see cref=\"AdoNetClusteringSiloOptions\"/> configuration.\n    /// </summary>\n    public class AdoNetClusteringSiloOptionsValidator : IConfigurationValidator\n    {\n        private readonly AdoNetClusteringSiloOptions options;\n\n        public AdoNetClusteringSiloOptionsValidator(IOptions<AdoNetClusteringSiloOptions> options)\n        {\n            this.options = options.Value;\n        }\n\n        /// <inheritdoc />\n        public void ValidateConfiguration()\n        {\n            if (string.IsNullOrWhiteSpace(this.options.Invariant))\n            {\n                throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetClusteringSiloOptions)} values for {nameof(AdoNetClusteringTable)}. {nameof(options.Invariant)} is required.\");\n            }\n\n            if (string.IsNullOrWhiteSpace(this.options.ConnectionString) == (this.options.DataSource is null))\n            {\n                throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetClusteringSiloOptions)} values for {nameof(AdoNetClusteringTable)}. Configure exactly one of {nameof(options.ConnectionString)} or {nameof(options.DataSource)}.\");\n            }\n        }\n    }\n}","sourceCodeStart":6,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AdoNet/Orleans.Clustering.AdoNet/Options/AdoNetReminderTableOptionsValidator.cs#L6-L33","documentation":"Thrown by AdoNetClusteringSiloOptionsValidator.ValidateConfiguration when the configured Invariant on the silo-side clustering/reminders options is null or whitespace. Despite the validator class name (AdoNetClusteringSiloOptionsValidator), it is used for the reminder table options and asserts that options.Invariant is present, since the invariant identifies which ADO.NET provider to load for the reminder store. It fails fast at startup with an OrleansConfigurationException.","triggerScenarios":"Produced at startup when AdoNetClusteringSiloOptions.Invariant is unset and the reminder options validator runs. Triggered by a missing/incomplete 'Invariant' in the AdoNet reminders configuration, a typo in the invariant string, or a config source returning empty.","commonSituations":"Appsettings section for reminders missing the Invariant field; partial config copied from clustering without the invariant; environment-specific config omitting the invariant; switching DB providers without updating the reminder provider.","solutions":["Set Invariant to the correct ADO.NET provider invariant for your database (e.g. 'Microsoft.Data.SqlClient', 'Npgsql', 'MySql.Data.MySqlClient').","Ensure the corresponding DbProviderFactory is registered and the provider package is installed.","Verify the reminder options section is the one being read by the validator (named options).","Reuse the same invariant you use for clustering/persistence for consistency across stores."],"exampleFix":"// before\nbuilder.UseAdoNetReminderService(options =>\n{\n    options.ConnectionString = \"Server=...;Database=OrleansReminders;...\";\n    // Invariant missing -> OrleansConfigurationException\n});\n\n// after\nbuilder.UseAdoNetReminderService(options =>\n{\n    options.ConnectionString = \"Server=...;Database=OrleansReminders;...\";\n    options.Invariant = \"Microsoft.Data.SqlClient\";\n});","handlingStrategy":"validation","validationCode":"// Validate reminder options at startup before the reminder service uses them\nif (string.IsNullOrWhiteSpace(reminderOptions.Invariant))\n    throw new OrleansConfigurationException(\"AdoNet reminder Invariant is required\");\nif (!DbProviderFactories.GetFactoryInvariantNames().Contains(reminderOptions.Invariant))\n    throw new OrleansConfigurationException($\"AdoNet provider invariant '{reminderOptions.Invariant}' is not registered\");","typeGuard":"static bool HasValidInvariant(AdoNetClusteringSiloOptions o) =>\n    !string.IsNullOrWhiteSpace(o.Invariant);","tryCatchPattern":"try { await silo.StartAsync(); }\ncatch (OrleansConfigurationException cx) when (cx.Message.Contains(\"Invariant is required\"))\n{\n    _logger.LogCritical(\"Set the AdoNet reminder Invariant (e.g. 'Microsoft.Data.SqlClient')\");\n    throw;\n}","preventionTips":["Always set Invariant in the AdoNet reminders config section.","Reuse the same ADO.NET invariant across clustering/persistence/reminders for consistency.","Register the DbProviderFactory and reference the provider package.","Validate the invariant against registered providers in a bootstrap check."],"tags":["adonet","reminders","config","validation","startup"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}