dotnet/orleans · error · OrleansConfigurationException

Invalid {nameof(AdoNetGrainStorageOptions)} values for {name

Error message

Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} {name}. {nameof(options.HashPicker)} is required.

What it means

Thrown by the AdoNetGrainStorageOptionsValidator when HashPicker is null. Normally DefaultAdoNetGrainStorageOptionsHashPickerConfigurator (an IPostConfigureOptions) supplies a default StorageHasherPicker at startup, so this fires only when that post-configure did not run — i.e., the grain storage was not registered through the proper AddAdoNetGrainStorage extension that wires the post-configurator, or HashPicker was explicitly nulled.

Source

Thrown at src/AdoNet/Orleans.Persistence.AdoNet/Options/AdoNetGrainStorageOptions.cs:107

            this.name = name;
        }

        /// <inheritdoc cref="IConfigurationValidator"/>
        public void ValidateConfiguration()
        {
            if (string.IsNullOrWhiteSpace(this.options.Invariant))
            {
                throw new OrleansConfigurationException($"Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} \"{name}\". {nameof(options.Invariant)} is required.");
            }

            if (string.IsNullOrWhiteSpace(this.options.ConnectionString) == (this.options.DataSource is null))
            {
                throw new OrleansConfigurationException($"Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} \"{name}\". Configure exactly one of {nameof(options.ConnectionString)} or {nameof(options.DataSource)}.");
            }

            if (this.options.HashPicker == null)
            {
                throw new OrleansConfigurationException($"Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} {name}. {nameof(options.HashPicker)} is required.");
            }
        }
    }

    /// <summary>
    /// Provides default configuration HashPicker for AdoNetGrainStorageOptions.
    /// </summary>
    public class DefaultAdoNetGrainStorageOptionsHashPickerConfigurator : IPostConfigureOptions<AdoNetGrainStorageOptions>
    {
        public void PostConfigure(string? name, AdoNetGrainStorageOptions options)
        {
            // preserving explicitly configured HashPicker
            if (options.HashPicker != null)
                return;

            // set default IHashPicker if not configured yet
            options.HashPicker = new StorageHasherPicker(new[] { new OrleansDefaultHasher() });
        }

View on GitHub (pinned to fca799fa70)

Solutions

  1. Register storage through AddAdoNetGrainStorage so DefaultAdoNetGrainStorageOptionsHashPickerConfigurator runs and sets the default HashPicker.
  2. Set options.HashPicker = new StorageHasherPicker(new[] { new OrleansDefaultHasher() }) manually if validating outside the host.
  3. Call options.UseOrleans3CompatibleHasher() if you need v3-compatible hashing, which also sets HashPicker.

Example fix

// before (manual/test path)
var options = new AdoNetGrainStorageOptions { /* ... */ };
new AdoNetGrainStorageOptionsValidator(options, "x").ValidateConfiguration(); // HashPicker null -> error

// after
options.HashPicker = new StorageHasherPicker(new[] { new OrleansDefaultHasher() });
new AdoNetGrainStorageOptionsValidator(options, "x").ValidateConfiguration();
Defensive patterns

Strategy: validation

Validate before calling

static void CheckHashPicker(AdoNetGrainStorageOptions o)
{
    if (o.HashPicker is null)
        throw new InvalidOperationException("HashPicker is null; register storage via AddAdoNetGrainStorage or set HashPicker manually.");
}

Prevention

When it happens

Trigger: ValidateConfiguration() runs with options.HashPicker == null because DefaultAdoNetGrainStorageOptionsHashPickerConfigurator never executed. Happens when AdoNetGrainStorageOptions is constructed and validated manually, or storage is registered via a low-level path that skips AddAdoNetGrainStorage.

Common situations: Manually new-ing up AdoNetGrainStorageOptions and its validator for testing; registering storage without the extension method that adds the post-configure; explicitly setting HashPicker = null after construction.

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/f7335fcb8f714b9c. Report an issue: GitHub.