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
- Register storage through AddAdoNetGrainStorage so DefaultAdoNetGrainStorageOptionsHashPickerConfigurator runs and sets the default HashPicker.
- Set options.HashPicker = new StorageHasherPicker(new[] { new OrleansDefaultHasher() }) manually if validating outside the host.
- 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
- Always register grain storage through AddAdoNetGrainStorage so the post-configure sets the default HashPicker.
- In unit tests that construct options directly, set HashPicker (or call UseOrleans3CompatibleHasher) before validating.
- Do not null HashPicker after construction.
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
- Invalid AdoNetGrainStorageOptions for AdoNetGrainStorage {na
- Invalid {nameof(AdoNetGrainDirectoryOptions)} values for {na
- Invalid {nameof(AdoNetGrainStorageOptions)} values for {name
- Invalid {nameof(AdoNetGrainStorageOptions)} values for {name
- Invalid {nameof(AdoNetClusteringSiloOptions)} values for {na
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/f7335fcb8f714b9c.
Report an issue: GitHub.