{"record":{"id":"565e32a0215b66e9","repo":"dotnet/orleans","slug":"invalid-adonetgrainstorageoptions-for-adonetgrains","errorCode":null,"errorMessage":"Invalid AdoNetGrainStorageOptions for AdoNetGrainStorage {name}. Options is required.","messagePattern":"Invalid AdoNetGrainStorageOptions for AdoNetGrainStorage (.+?)\\. Options is required\\.","errorType":"validation","errorClass":"OrleansConfigurationException","httpStatus":null,"severity":"error","filePath":"src/AdoNet/Orleans.Persistence.AdoNet/Options/AdoNetGrainStorageOptions.cs","lineNumber":88,"sourceCode":"        public bool DeleteStateOnClear { get; set; }\n    }\n\n    /// <summary>\n    /// ConfigurationValidator for AdoNetGrainStorageOptions\n    /// </summary>\n    public class AdoNetGrainStorageOptionsValidator : IConfigurationValidator\n    {\n        private readonly AdoNetGrainStorageOptions options;\n        private readonly string name;\n\n        /// <summary>\n        /// Constructor\n        /// </summary>\n        /// <param name=\"configurationOptions\">The option to be validated.</param>\n        /// <param name=\"name\">The name of the option to be validated.</param>\n        public AdoNetGrainStorageOptionsValidator(AdoNetGrainStorageOptions configurationOptions, string name)\n        {\n            this.options = configurationOptions ?? throw new OrleansConfigurationException($\"Invalid AdoNetGrainStorageOptions for AdoNetGrainStorage {name}. Options is required.\");\n            this.name = name;\n        }\n\n        /// <inheritdoc cref=\"IConfigurationValidator\"/>\n        public void ValidateConfiguration()\n        {\n            if (string.IsNullOrWhiteSpace(this.options.Invariant))\n            {\n                throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} \\\"{name}\\\". {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(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} \\\"{name}\\\". Configure exactly one of {nameof(options.ConnectionString)} or {nameof(options.DataSource)}.\");\n            }\n\n            if (this.options.HashPicker == null)\n            {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AdoNet/Orleans.Persistence.AdoNet/Options/AdoNetGrainStorageOptions.cs#L70-L106","documentation":"Thrown by the AdoNetGrainStorageOptionsValidator constructor when the configurationOptions argument is null. This is a defensive null-check at validator construction time and indicates the DI container resolved a null AdoNetGrainStorageOptions for the given storage name.","triggerScenarios":"The validator is instantiated (typically by the options/validation infrastructure at host startup) with a null AdoNetGrainStorageOptions. Occurs when AddAdoNetGrainStorage(name) is called without a matching Configure<AdoNetGrainStorageOptions>(name, ...) binding, so DI returns null.","commonSituations":"Registering named grain storage \"profile\" but configuring options under a different name or no name; misordered Configure calls; custom DI setup that returns default for the options type.","solutions":["Add a Configure<AdoNetGrainStorageOptions>(name, ...) binding whose name matches the AddAdoNetGrainStorage(name) call.","Use the AddAdoNetGrainStorage(name, configureOptions) overload which binds both registration and options.","Verify the storage name string is identical in AddGrainStorage/AddAdoNetGrainStorage and the options delegate."],"exampleFix":"// before\nbuilder.AddAdoNetGrainStorage(\"profile\"); // no options delegate\n\n// after\nbuilder.AddAdoNetGrainStorage(\"profile\", o =>\n{\n    o.Invariant = AdoNetInvariants.InvariantNameSqlServer;\n    o.ConnectionString = \"Server=.;Database=Orleans;\";\n});","handlingStrategy":"validation","validationCode":"// Confirm the named storage options resolve.\nvar resolved = serviceProvider.GetService<IOptionsMonitor<AdoNetGrainStorageOptions>>()?.Get(name);\nif (resolved is null) throw new InvalidOperationException($\"AdoNetGrainStorageOptions '{name}' not registered.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use AddAdoNetGrainStorage(name, configureOptions) to bind registration and options.","Keep storage names identical across AddGrainStorage and Configure calls.","Write a DI resolution test for each named storage options."],"tags":["configuration","adonet","grain-storage","dependency-injection","startup-validation"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}