{"record":{"id":"ab57e5b476cb3e11","repo":"dotnet/orleans","slug":"nameof-options-deletestateonclear-true-is-not-s","errorCode":null,"errorMessage":"{nameof(options.DeleteStateOnClear)}=true is not supported. Use {nameof(options.DeleteStateOnClear)}=false instead or check persistence scripts.","messagePattern":"(.+?)=true is not supported\\. Use (.+?)=false instead or check persistence scripts\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/AdoNet/Orleans.Persistence.AdoNet/Storage/Provider/AdoNetGrainStorage.cs","lineNumber":348,"sourceCode":"            LogTraceWroteGrainState(serviceId, name, baseGrainType, grainId, grainState.ETag);\n        }\n\n        /// <summary> Initialization function for this storage provider. </summary>\n        private async Task Init(CancellationToken cancellationToken)\n        {\n            Storage = RelationalStorage.CreateInstance(options.Invariant, options.ConnectionString, options.DataSource);\n            var queries = await Storage.ReadAsync(DefaultInitializationQuery, command => { }, (selector, resultSetCount, token) =>\n            {\n                return Task.FromResult(Tuple.Create(selector.GetValue<string>(\"QueryKey\"), selector.GetValue<string>(\"QueryText\")));\n            }).ConfigureAwait(false);\n\n            // This check is for backward compatibility:\n            // 1. Some AdoNet storage invariants may not support delete on clear.\n            // 2. AdoNet invariant supports delete on clear but updated persistence scripts have not been deployed to management db.\n            var deleteStateQuery = queries.SingleOrDefault(i => i.Item1 == \"DeleteStorageKey\")?.Item2;\n            if (options.DeleteStateOnClear && deleteStateQuery is null)\n            {\n                throw new ArgumentException($\"{nameof(options.DeleteStateOnClear)}=true is not supported. Use {nameof(options.DeleteStateOnClear)}=false instead or check persistence scripts.\");\n            }\n            CurrentOperationalQueries = new RelationalStorageProviderQueries(\n                queries.Single(i => i.Item1 == \"WriteToStorageKey\").Item2,\n                queries.Single(i => i.Item1 == \"ReadFromStorageKey\").Item2,\n                queries.Single(i => i.Item1 == \"ClearStorageKey\").Item2,\n                deleteStateQuery);\n\n            LogInfoInitializedStorageProvider(\n                serviceId,\n                name,\n                Storage.InvariantName,\n                new(Storage.ConnectionString));\n        }\n\n        /// <summary>\n        /// Close this provider\n        /// </summary>\n        private Task Close(CancellationToken token)","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AdoNet/Orleans.Persistence.AdoNet/Storage/Provider/AdoNetGrainStorage.cs#L330-L366","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbuilder.AddAdoNetGrainStorage(\"profile\", o =>\n{\n    o.DeleteStateOnClear = true; // scripts lack DeleteStorageKey -> error at init\n});\n\n// after (option A: deploy scripts, option B: disable)\nbuilder.AddAdoNetGrainStorage(\"profile\", o =>\n{\n    o.DeleteStateOnClear = false;\n});","handlingStrategy":"validation","validationCode":"// Before enabling DeleteStateOnClear, confirm the scripts include the query.\nvar hasDelete = await QueriesContainKeyAsync(storage, \"DeleteStorageKey\");\nif (options.DeleteStateOnClear && !hasDelete)\n    throw new InvalidOperationException(\"Deploy persistence scripts with DeleteStorageKey before enabling DeleteStateOnClear.\");","typeGuard":null,"tryCatchPattern":"try { await grainStorage.Init(); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"DeleteStateOnClear\"))\n{\n    // deploy scripts or disable DeleteStateOnClear, then restart.\n}","preventionTips":["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."],"tags":["adonet","grain-storage","delete-on-clear","persistence-scripts","runtime"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}