dotnet/aspnetcore · error · InvalidOperationException
State already initialized.
Error message
State already initialized.
What it means
ComponentStatePersistenceManager.RestoreStateAsync guards the single-initialization invariant: once _stateIsInitialized is true, the only legal re-entry is with RestoreContext.ValueUpdate (which routes to State.UpdateExistingState). Any other restore context on an already-initialized manager means a second full initialization is being attempted, which would re-run service registration and double-bind restoring callbacks, so the manager throws.
Solutions
- Call RestoreStateAsync(store) at most once per manager lifetime; for subsequent state refreshes use RestoreStateAsync(store, RestoreContext.ValueUpdate).
- Ensure each store or middleware layer restores exactly once; if multiple stores participate, route updates through the ValueUpdate context rather than re-initializing.
- If you need a fresh full restore, construct a new ComponentStatePersistenceManager instead of reusing the initialized one.
Example fix
// before: double restore with default context await manager.RestoreStateAsync(store); await manager.RestoreStateAsync(store); // throws // after: use ValueUpdate for subsequent restores await manager.RestoreStateAsync(store); await manager.RestoreStateAsync(store, RestoreContext.ValueUpdate);
Defensive patterns
Strategy: validation
Validate before calling
// Track restore state in your host to avoid double-initialization.
if (!_restoreDone)
{
await manager.RestoreStateAsync(store);
_restoreDone = true;
}
else
{
// subsequent refreshes must use ValueUpdate
await manager.RestoreStateAsync(store, RestoreContext.ValueUpdate);
} Prevention
- Call RestoreStateAsync(store) exactly once per manager; use ValueUpdate for later passes.
- Centralize restore invocation in a single middleware/endpoint to prevent duplicate calls.
- For tests, construct a fresh manager per restore scenario.
When it happens
Trigger: Calling RestoreStateAsync(store) (the single-argument overload, which uses RestoreContext.InitialValue) twice on the same ComponentStatePersistenceManager instance. Or calling RestoreStateAsync(store, RestoreContext.InitialValue) after a prior restore completed. The host or a custom middleware invoking restore more than once for the same request/circuit without switching to ValueUpdate.
Common situations: A Blazor Web App endpoint or middleware that runs prerender restore and then, due to a misconfigured pipeline, restores again for the same render. Wiring multiple IPersistentComponentStateStore providers that each call RestoreStateAsync with the default context. Custom hosting that reuses a single manager across prerender and interactive startup.
Related errors
- Cannot update existing state: previous state has not been…
- State already persisted.
- A public property ' ' on component type ' ' with a public…
- Dynamic root components have not been enabled in this…
- ' ' has not been initialized.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/ca6ea4a5200f0dfa.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/PersistentState/ComponentStatePersistenceManager.cs:78
{
await RestoreStateAsync(store, RestoreContext.InitialValue);
}
/// <summary>
/// Restores the application state.
/// </summary>
/// <param name="store"> The <see cref="IPersistentComponentStateStore"/> to restore the application state from.</param>
/// <param name="context">The <see cref="RestoreContext"/> that provides additional context for the restoration.</param>
/// <returns>A <see cref="Task"/> that will complete when the state has been restored.</returns>
public async Task RestoreStateAsync(IPersistentComponentStateStore store, RestoreContext context)
{
var data = await store.GetPersistedStateAsync();
if (_stateIsInitialized)
{
if (context != RestoreContext.ValueUpdate)
{
throw new InvalidOperationException("State already initialized.");
}
State.UpdateExistingState(data, context);
foreach (var registration in _registeredRestoringCallbacks)
{
registration.Callback();
}
}
else
{
State.InitializeExistingState(data, context);
_servicesRegistry?.RegisterForPersistence(State);
_stateIsInitialized = true;
}
}
/// <summary>
/// Persists the component application state into the given <see cref="IPersistentComponentStateStore"/>.
/// </summary>View on GitHub (pinned to 3600ca084e)