dotnet/orleans · error · ArgumentException
{nameof(options.DeleteStateOnClear)}=true is not supported.
Error message
{nameof(options.DeleteStateOnClear)}=true is not supported. Use {nameof(options.DeleteStateOnClear)}=false instead or check persistence scripts. What it means
Thrown at runtime during ADO.NET grain storage initialization when DeleteStateOnClear is true but the loaded persistence scripts contain no DeleteStorageKey query. It is a backward-compatibility guard: some ADO.NET invariants or deployed script sets do not support delete-on-clear, so Orleans refuses to start rather than silently skipping deletes.
Source
Thrown at src/AdoNet/Orleans.Persistence.AdoNet/Storage/Provider/AdoNetGrainStorage.cs:348
LogTraceWroteGrainState(serviceId, name, baseGrainType, grainId, grainState.ETag);
}
/// <summary> Initialization function for this storage provider. </summary>
private async Task Init(CancellationToken cancellationToken)
{
Storage = RelationalStorage.CreateInstance(options.Invariant, options.ConnectionString, options.DataSource);
var queries = await Storage.ReadAsync(DefaultInitializationQuery, command => { }, (selector, resultSetCount, token) =>
{
return Task.FromResult(Tuple.Create(selector.GetValue<string>("QueryKey"), selector.GetValue<string>("QueryText")));
}).ConfigureAwait(false);
// This check is for backward compatibility:
// 1. Some AdoNet storage invariants may not support delete on clear.
// 2. AdoNet invariant supports delete on clear but updated persistence scripts have not been deployed to management db.
var deleteStateQuery = queries.SingleOrDefault(i => i.Item1 == "DeleteStorageKey")?.Item2;
if (options.DeleteStateOnClear && deleteStateQuery is null)
{
throw new ArgumentException($"{nameof(options.DeleteStateOnClear)}=true is not supported. Use {nameof(options.DeleteStateOnClear)}=false instead or check persistence scripts.");
}
CurrentOperationalQueries = new RelationalStorageProviderQueries(
queries.Single(i => i.Item1 == "WriteToStorageKey").Item2,
queries.Single(i => i.Item1 == "ReadFromStorageKey").Item2,
queries.Single(i => i.Item1 == "ClearStorageKey").Item2,
deleteStateQuery);
LogInfoInitializedStorageProvider(
serviceId,
name,
Storage.InvariantName,
new(Storage.ConnectionString));
}
/// <summary>
/// Close this provider
/// </summary>
private Task Close(CancellationToken token)View on GitHub (pinned to fca799fa70)
Solutions
- Deploy/re-run the current Orleans persistence scripts (e.g. SQLServer-Persistence.sql) so the DeleteStorageKey query row exists.
- Set options.DeleteStateOnClear = false to keep clear-as-blank behavior without deleting the row.
- Verify the management database's QueryKey rows include DeleteStorageKey after script deployment.
Example fix
// before
builder.AddAdoNetGrainStorage("profile", o =>
{
o.DeleteStateOnClear = true; // scripts lack DeleteStorageKey -> error at init
});
// after (option A: deploy scripts, option B: disable)
builder.AddAdoNetGrainStorage("profile", o =>
{
o.DeleteStateOnClear = false;
}); Defensive patterns
Strategy: validation
Validate before calling
// Before enabling DeleteStateOnClear, confirm the scripts include the query.
var hasDelete = await QueriesContainKeyAsync(storage, "DeleteStorageKey");
if (options.DeleteStateOnClear && !hasDelete)
throw new InvalidOperationException("Deploy persistence scripts with DeleteStorageKey before enabling DeleteStateOnClear."); Try / catch
try { await grainStorage.Init(); }
catch (ArgumentException ex) when (ex.Message.Contains("DeleteStateOnClear"))
{
// deploy scripts or disable DeleteStateOnClear, then restart.
} Prevention
- Run the latest Orleans persistence scripts for your DB before enabling DeleteStateOnClear.
- Verify the management DB has a DeleteStorageKey row after deployment.
- Keep DeleteStateOnClear=false until scripts are confirmed, then flip it.
When it happens
Trigger: AdoNetGrainStorage reads the initialization queries from the database (DefaultInitializationQuery) during Init; if options.DeleteStateOnClear == true and no row with QueryKey == "DeleteStorageKey" is present, it throws ArgumentException at init stage.
Common situations: Enabling DeleteStateOnClear on a database whose Orleans persistence scripts are from an older version that predates the DeleteStorageKey script; deploying SQL Server scripts but pointing at a database only initialized for an older schema; partial script deployment.
Related errors
- Invalid AdoNetGrainStorageOptions for AdoNetGrainStorage {na
- Invalid {nameof(AdoNetGrainStorageOptions)} values for {name
- Invalid {nameof(AdoNetGrainStorageOptions)} values for {name
- Invalid {nameof(AdoNetGrainStorageOptions)} values for {name
- Cannot get events from a half-baked {nameof(AdoNetBatchConta
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/ab57e5b476cb3e11.
Report an issue: GitHub.