dotnet/aspnetcore · error · InvalidOperationException
Registering a callback while persisting state is not…
Error message
Registering a callback while persisting state is not allowed.
What it means
Thrown by RegisterOnPersisting when PersistingState is already true. Persist callbacks may only be registered before the persistence phase begins; once the framework starts invoking persisters, registering a new one would either miss the current cycle or re-enter it, both of which are unsafe.
Solutions
- Register persist callbacks during normal component initialization (OnInitialized/OnInitializedAsync), not from inside another persist callback.
- If a callback depends on dynamically discovered state, register a single stable callback early and resolve the state inside it.
- Avoid rendering new components during the persistence phase; defer their creation until after persistence completes.
- In a custom host, finish all registrations before setting PersistingState = true.
Example fix
// before: register lazily inside another persist callback
state.RegisterOnPersisting(async () =>
{
state.RegisterOnPersisting(PersistExtra); // throws
await PersistMain();
});
// after: register both up front in OnInitialized
public class MyComponent : ComponentBase
{
[Inject] PersistentComponentState State { get; set; } = default!;
protected override void OnInitialized()
{
State.RegisterOnPersisting(PersistMain);
State.RegisterOnPersisting(PersistExtra);
}
} Defensive patterns
Strategy: validation
Validate before calling
if (state.PersistingState) throw new InvalidOperationException("Cannot register now; persist phase is running.");
state.RegisterOnPersisting(callback); Try / catch
try { sub = state.RegisterOnPersisting(callback); }
catch (InvalidOperationException ex) when (ex.Message.Contains("while persisting state is not allowed"))
{ /* defer registration to the next init cycle */ } Prevention
- Register all persist callbacks during OnInitializedAsync, before persistence starts.
- Do not render new components during the persistence phase.
- In a custom host, close registration before setting PersistingState = true.
When it happens
Trigger: Calling PersistentComponentState.RegisterOnPersisting(...) from inside another persisting callback, or from a component whose OnInitialized runs during the persistence pass. The flag flips true while the framework enumerates and invokes registered callbacks.
Common situations: A component dynamically rendered during persist; calling RegisterOnPersisting lazily on first persist; a callback that triggers a re-render that registers another callback; misuse in custom hosting where persistence is invoked manually while still accepting registrations.
Related errors
- PersistentComponentState already initialized.
- Persisting state is only allowed during an OnPersisting…
- existingState
- State already persisted.
- There is already a persisted object under the same key
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/5dfac554fb55d9f0.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/PersistentComponentState.cs:68
/// <param name="callback">The callback to invoke when the application is being paused.</param>
/// <returns>A subscription that can be used to unregister the callback when disposed.</returns>
public PersistingComponentStateSubscription RegisterOnPersisting(Func<Task> callback)
=> RegisterOnPersisting(callback, null);
/// <summary>
/// Register a callback to persist the component state when the application is about to be paused.
/// Registered callbacks can use this opportunity to persist their state so that it can be retrieved when the application resumes.
/// </summary>
/// <param name="callback">The callback to invoke when the application is being paused.</param>
/// <param name="renderMode"></param>
/// <returns>A subscription that can be used to unregister the callback when disposed.</returns>
public PersistingComponentStateSubscription RegisterOnPersisting(Func<Task> callback, IComponentRenderMode? renderMode)
{
ArgumentNullException.ThrowIfNull(callback);
if (PersistingState)
{
throw new InvalidOperationException("Registering a callback while persisting state is not allowed.");
}
var persistenceCallback = new PersistComponentStateRegistration(callback, renderMode);
_registeredCallbacks.Add(persistenceCallback);
return new PersistingComponentStateSubscription(_registeredCallbacks, persistenceCallback);
}
/// <summary>
/// Register a callback to restore the state when the application state is being restored.
/// </summary>
/// <param name="callback"> The callback to invoke when the application state is being restored.</param>
/// <param name="options">Options that control the restoration behavior.</param>
/// <returns>A subscription that can be used to unregister the callback when disposed.</returns>
public RestoringComponentStateSubscription RegisterOnRestoring(Action callback, RestoreOptions options)
{
Debug.Assert(CurrentContext != null);View on GitHub (pinned to 3600ca084e)