{"record":{"id":"56dd24853a162e43","repo":"dotnet/orleans","slug":"invalid-nameof-adonetclusteringclientoptions-va-56dd24","errorCode":null,"errorMessage":"Invalid {nameof(AdoNetClusteringClientOptions)} values for {nameof(AdoNetClusteringTable)}. Configure exactly one of {nameof(options.ConnectionString)} or {nameof(options.DataSource)}.","messagePattern":"Invalid (.+?) values for (.+?)\\. Configure exactly one of (.+?) or (.+?)\\.","errorType":"validation","errorClass":"OrleansConfigurationException","httpStatus":null,"severity":"error","filePath":"src/AdoNet/Orleans.Clustering.AdoNet/Options/AdoNetClusteringClientOptionsValidator.cs","lineNumber":29,"sourceCode":"    {\n        private readonly AdoNetClusteringClientOptions options;\n\n        public AdoNetClusteringClientOptionsValidator(IOptions<AdoNetClusteringClientOptions> 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(AdoNetClusteringClientOptions)} 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(AdoNetClusteringClientOptions)} values for {nameof(AdoNetClusteringTable)}. Configure exactly one of {nameof(options.ConnectionString)} or {nameof(options.DataSource)}.\");\n            }\n        }\n    }\n}","sourceCodeStart":11,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AdoNet/Orleans.Clustering.AdoNet/Options/AdoNetClusteringClientOptionsValidator.cs#L11-L33","documentation":"Thrown by AdoNetClusteringClientOptionsValidator.ValidateConfiguration when exactly one of ConnectionString or DataSource is not configured. The condition `IsNullOrWhiteSpace(ConnectionString) == (DataSource is null)` is true when both are set or both are unset, which the provider rejects because it needs exactly one source of database connectivity. ConnectionString is a full ADO.NET connection string; DataSource lets you supply a DbDataSource (e.g. NpgsqlDataSource) instead.","triggerScenarios":"Produced at startup when both ConnectionString and DataSource are provided, or when neither is provided. Triggered by setting both fields (ambiguous), by leaving both empty, or by a config edit that removed the connection string while a DataSource was never wired up.","commonSituations":"Migrating from ConnectionString to DbDataSource and accidentally leaving both populated; config template that sets ConnectionString to empty string while DataSource stays null; copy-paste between environments dropping the connection string; using DbDataSource injection without removing the legacy connection string.","solutions":["Provide exactly one connectivity source: either ConnectionString (classic) or DataSource (DbDataSource), not both, not neither.","If migrating to DbDataSource, clear/omit ConnectionString from the options.","If using a plain connection string, leave DataSource unset and ensure ConnectionString is non-empty.","Validate the config section is not setting ConnectionString to an empty string (whitespace counts as unset)."],"exampleFix":"// before: both set\noptions.ConnectionString = \"Server=...;...\";\noptions.DataSource = npgsqlDataSource;\n\n// after: keep exactly one\noptions.DataSource = npgsqlDataSource;\n// (ConnectionString left null/unset)","handlingStrategy":"validation","validationCode":"// Enforce exactly-one connectivity source before the silo uses clustering\nbool hasCs = !string.IsNullOrWhiteSpace(options.ConnectionString);\nbool hasDs = options.DataSource is not null;\nif (hasCs == hasDs)\n    throw new OrleansConfigurationException(\"Configure exactly one of ConnectionString or DataSource for AdoNet clustering\");","typeGuard":"static bool HasExactlyOneConnectionSource(AdoNetClusteringClientOptions o) =>\n    !string.IsNullOrWhiteSpace(o.ConnectionString) ^ (o.DataSource is not null);","tryCatchPattern":"try { await client.Connect(); }\ncatch (OrleansConfigurationException cx) when (cx.Message.Contains(\"Configure exactly one of\"))\n{\n    _logger.LogCritical(\"Provide exactly one of ConnectionString or DataSource for AdoNet clustering\");\n    throw;\n}","preventionTips":["When migrating to DbDataSource, clear the legacy ConnectionString.","Treat empty/whitespace ConnectionString as unset.","Validate the exactly-one invariant in a bootstrap check at startup.","Do not copy-paste config blocks without reconciling both fields."],"tags":["adonet","clustering","config","validation","connection-string"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}