{"record":{"id":"2b594bf9aed6eb21","repo":"stride3d/stride","slug":"an-error-occurred-while-removing-an-item-to-the-node-see-the","errorCode":null,"errorMessage":"An error occurred while removing an item to the node, see the inner exception for more information.","messagePattern":"An error occurred while removing an item to the node, see the inner exception for more information\\.","errorType":"exception","errorClass":"NodePresenterException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Quantum/Presenters/ItemNodePresenter.cs","lineNumber":114,"sourceCode":"        }\n        catch (Exception e)\n        {\n            throw new NodePresenterException(\"An error occurred while adding an item to the node, see the inner exception for more information.\", e);\n        }\n    }\n\n    public override void RemoveItem(object value, NodeIndex index)\n    {\n        if (Container.IndexedTarget(Index)?.IsEnumerable != true)\n            throw new NodePresenterException($\"{nameof(MemberNodePresenter)}.{nameof(AddItem)} cannot be invoked on members that are not collection.\");\n\n        try\n        {\n            Container.IndexedTarget(Index).Remove(value, index);\n        }\n        catch (Exception e)\n        {\n            throw new NodePresenterException(\"An error occurred while removing an item to the node, see the inner exception for more information.\", e);\n        }\n    }\n\n    public override NodeAccessor GetNodeAccessor()\n    {\n        return new NodeAccessor(Container, Index);\n    }\n\n    private void OnItemChanging(object? sender, ItemChangeEventArgs e)\n    {\n        if (IsValidChange(e))\n            RaiseValueChanging(e.NewValue);\n    }\n\n    private void OnItemChanged(object? sender, ItemChangeEventArgs e)\n    {\n        if (IsValidChange(e))\n        {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Quantum/Presenters/ItemNodePresenter.cs#L96-L132","documentation":"ItemNodePresenter.RemoveItem(value, index) wraps any exception thrown by Container.IndexedTarget(Index).Remove(value, index) in a NodePresenterException. The library centralizes collection-removal failures into NodePresenterException; diagnose via InnerException. Typical inner causes are an index/key that no longer exists, an item that is not present, or removal not being supported by the underlying collection.","triggerScenarios":"Calling ItemNodePresenter.RemoveItem(value, index) when the NodeIndex is stale (item already removed or collection shifted), the key does not exist in a dictionary, the value does not match the item stored at that index, or the underlying collection (array, IReadOnlyList) has no working Remove implementation.","commonSituations":"Editor UI removing a row after the model was reloaded or reordered elsewhere (stale NodeIndex); removing by a dictionary key that was renamed; calling RemoveItem on a node whose collection became read-only after a serialization round-trip.","solutions":["Catch NodePresenterException and inspect InnerException for the exact cause.","Verify the item still exists at the given index (Container.Retrieve(Index)) before removing, and refresh the presenter if the collection changed.","Check that the collection type actually supports removal (not an array or read-only wrapper).","Use the current NodeIndex from the presenter/UI selection rather than a cached one."],"exampleFix":"// before\npresenter.RemoveItem(item, cachedIndex); // index stale after reload -> wrapped exception\n// after\nvar current = (IList)containerNode.Retrieve();\nint i = current.IndexOf(item);\nif (i >= 0)\n    presenter.RemoveItem(item, new NodeIndex(i));","handlingStrategy":"validation","validationCode":"var target = presenter.Container.IndexedTarget(presenter.Index);\nif (target == null || !target.IsEnumerable) return;\nvar current = target.Retrieve();\nbool exists = index.IsInt\n    ? index.Int < ((IList)current).Count\n    : current is System.Collections.IDictionary d && d.Contains(index.Value);\nif (!exists) throw new InvalidOperationException(\"Item no longer exists at this index; refresh the presenter.\");","typeGuard":"static bool CanRemove(ItemNodePresenter p, NodeIndex index)\n    => p.Container.IndexedTarget(p.Index)?.IsEnumerable == true\n       && index != NodeIndex.Empty;","tryCatchPattern":"try\n{\n    itemPresenter.RemoveItem(value, index);\n}\ncatch (NodePresenterException ex)\n{\n    // stale index or unsupported removal\n    RefreshPresenter();\n    logger.Warn(ex.InnerException, \"Remove failed; presenter refreshed\");\n}","preventionTips":["Verify the item still exists at the index before removing (Retrieve first).","Never cache NodeIndex values across model reloads or reorder operations.","Ensure the collection type supports Remove (avoid arrays/read-only wrappers in models).","Refresh presenters after external changes so indices stay in sync."],"tags":["dotnet","stride","quantum","collection","removal","wrapped-exception"],"backgroundTag":"record-not-found","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}