{"record":{"id":"7cfa7eee05317713","repo":"dotnet/aspnetcore","slug":"persisting-state-is-only-allowed-during-an-onpersi","errorCode":null,"errorMessage":"Persisting state is only allowed during an OnPersisting callback.","messagePattern":"Persisting state is only allowed during an OnPersisting callback\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/PersistentComponentState.cs","lineNumber":115,"sourceCode":"        }\n\n        return default;\n    }\n\n    /// <summary>\n    /// Serializes <paramref name=\"instance\"/> as JSON and persists it under the given <paramref name=\"key\"/>.\n    /// </summary>\n    /// <typeparam name=\"TValue\">The <paramref name=\"instance\"/> type.</typeparam>\n    /// <param name=\"key\">The key to use to persist the state.</param>\n    /// <param name=\"instance\">The instance to persist.</param>\n    [RequiresUnreferencedCode(\"JSON serialization and deserialization might require types that cannot be statically analyzed.\")]\n    public void PersistAsJson<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string key, TValue instance)\n    {\n        ArgumentNullException.ThrowIfNull(key);\n\n        if (!PersistingState)\n        {\n            throw new InvalidOperationException(\"Persisting state is only allowed during an OnPersisting callback.\");\n        }\n\n        if (!_currentState.TryAdd(key, JsonSerializer.SerializeToUtf8Bytes(instance, JsonSerializerOptionsProvider.Options)))\n        {\n            throw new ArgumentException($\"There is already a persisted object under the same key '{key}'\");\n        }\n    }\n\n    [RequiresUnreferencedCode(\"JSON serialization and deserialization might require types that cannot be statically analyzed.\")]\n    internal void PersistAsJson(string key, object instance, [DynamicallyAccessedMembers(JsonSerialized)] Type type)\n    {\n        ArgumentNullException.ThrowIfNull(key);\n\n        if (!PersistingState)\n        {\n            throw new InvalidOperationException(\"Persisting state is only allowed during an OnPersisting callback.\");\n        }\n","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/PersistentComponentState.cs#L97-L133","documentation":"Thrown by the public PersistAsJson<T> when PersistingState is false. PersistentComponentState only allows writing during the OnPersisting phase so that persisted data is consistent and captured before the application is paused. Calling PersistAsJson outside that window would write data the host will never serialize or transmit.","triggerScenarios":"Invoking state.PersistAsJson(key, instance) from OnInitializedAsync, a button click handler, OnParametersSet, or any code path outside an OnPersisting-registered callback. The PersistingState flag is only true while the framework is running the persist callbacks.","commonSituations":"Persisting on demand from an event handler instead of from a registered callback; misunderstanding the lifecycle and assuming PersistAsJson can be called any time; refactoring that moved a PersistAsJson call out of a callback.","solutions":["Move the PersistAsJson call inside a callback registered via RegisterOnPersisting.","Capture the data you need into a field during normal execution, then read that field inside the OnPersisting callback to persist it.","Do not expose PersistentComponentState to code that runs outside the persist phase (e.g. a long-running service).","If you need persistence outside the framework cycle, use your own storage; PersistentComponentState is lifecycle-bound."],"exampleFix":"// before: called from an event handler - outside the persist phase\nprivate void OnSave() => state.PersistAsJson(\"profile\", _profile); // throws\n\n// after: stash the value and persist it from the registered callback\nprivate UserProfile _profile = new();\nprotected override void OnInitialized()\n    => state.RegisterOnPersisting(() => { state.PersistAsJson(\"profile\", _profile); return Task.CompletedTask; });\nprivate void OnSave() => _profile = ComputeProfile();","handlingStrategy":"validation","validationCode":"if (!state.PersistingState) throw new InvalidOperationException(\"PersistAsJson must run inside an OnPersisting callback.\");","typeGuard":null,"tryCatchPattern":"try { state.PersistAsJson(key, instance); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"only allowed during an OnPersisting callback\"))\n{ /* move the call inside a RegisterOnPersisting callback */ }","preventionTips":["Register a persist callback once in OnInitialized and write all state from it.","Capture the live data in a field; read the field inside the callback.","Do not expose PersistentComponentState to code outside the component lifecycle."],"tags":["blazor","state","persistence","lifecycle"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}