{"record":{"id":"3d8b1a39b88c27ed","repo":"dotnet/aspnetcore","slug":"cannot-update-existing-state-previous-state-has-n","errorCode":null,"errorMessage":"Cannot update existing state: previous state has not been cleared or state is not initialized.","messagePattern":"Cannot update existing state: previous state has not been cleared or state is not initialized\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/PersistentComponentState.cs","lineNumber":249,"sourceCode":"\n        if (_existingState.TryGetValue(key, out value))\n        {\n            _existingState.Remove(key);\n            return true;\n        }\n        else\n        {\n            return false;\n        }\n    }\n\n    internal void UpdateExistingState(IDictionary<string, byte[]> state, RestoreContext context)\n    {\n        ArgumentNullException.ThrowIfNull(state);\n\n        if (_existingState == null || _existingState.Count > 0)\n        {\n            throw new InvalidOperationException(\"Cannot update existing state: previous state has not been cleared or state is not initialized.\");\n        }\n\n        _existingState = state;\n        CurrentContext = context;\n    }\n}\n","sourceCodeStart":231,"sourceCodeEnd":256,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/PersistentComponentState.cs#L231-L256","documentation":"Thrown by PersistentComponentState.UpdateExistingState when _existingState is null (state was never initialized via InitializeExistingState) OR when _existingState.Count > 0 (previously restored entries were never consumed via TryTake). UpdateExistingState is called from RestoreStateAsync only when the context is RestoreContext.ValueUpdate, i.e. during an in-place value update rather than the initial restore.","triggerScenarios":"Calling RestoreStateAsync(store, RestoreContext.ValueUpdate) before the initial RestoreStateAsync(store) has run; or after a restore where some persisted keys were never consumed by TryTakeFromJson/TryTakeBytes, leaving _existingState non-empty when the next ValueUpdate arrives.","commonSituations":"A custom IPersistentComponentStateStore or host that drives multiple restore cycles (e.g. streaming updates) but skips the initial restore; a persistent service/component that registers a restoring callback but does not consume its key on update; partial consumption of state across value-update cycles.","solutions":["Ensure the initial RestoreStateAsync(store) (default RestoreContext.InitialValue) runs exactly once before any RestoreContext.ValueUpdate restore.","Make sure every persisted key is consumed (TryTake*) on each cycle so _existingState is empty before the next update.","If some keys must survive across updates, restructure the store to return a fresh dictionary for value updates instead of relying on leftover entries.","Audit restoring callbacks to confirm they all call TryTakeFromJson/TryTakeBytes for their keys."],"exampleFix":"// before: restoring callback registered but never consumes its key\nstate.RegisterOnRestoring(() => { /* reads _local, never calls TryTake */ });\n\n// after: consume the key on every restore\nstate.RegisterOnRestoring(() =>\n{\n    if (state.TryTakeFromJson<Cart>(\"cart\", out var restored))\n        _local = restored;\n});","handlingStrategy":"validation","validationCode":"// In a custom store/host: ensure the initial restore ran and prior state was consumed\n// before issuing a ValueUpdate restore.\nbool CanValueUpdate(ComponentStatePersistenceManager m)\n    => m.State.CurrentContext != RestoreContext.InitialValue; // simplistic gate\n\n// Stronger: ensure your restoring callbacks always consume their keys so existingState empties.","typeGuard":null,"tryCatchPattern":"try\n{\n    await manager.RestoreStateAsync(store, RestoreContext.ValueUpdate);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Cannot update existing state\"))\n{\n    // state never initialized or not fully consumed - reinitialize instead\n    await manager.RestoreStateAsync(store); // fresh initial restore\n}","preventionTips":["Always run the initial RestoreStateAsync(store) once before any ValueUpdate restore.","Make every restoring callback consume its key via TryTakeFromJson/TryTakeBytes on each cycle.","Audit your persistent service/component restoring callbacks for keys they never consume.","Return a fresh empty dictionary from your store on value updates if keys need not survive."],"tags":["blazor","component-state","persistence","restore","lifecycle"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}