{"record":{"id":"6ec43e58d82d2b67","repo":"stride3d/stride","slug":"an-error-occurred-while-adding-an-item-to-the-node-see-the","errorCode":null,"errorMessage":"An error occurred while adding an item to the node, see the inner exception for more information.","messagePattern":"An error occurred while adding 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":84,"sourceCode":"        }\n        catch (Exception e)\n        {\n            throw new NodePresenterException(\"An error occurred while updating the value of the node, see the inner exception for more information.\", e);\n        }\n    }\n\n    public override void AddItem(object value)\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).Add(value);\n        }\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 AddItem(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).Add(value, index);\n        }\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","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Quantum/Presenters/ItemNodePresenter.cs#L66-L102","documentation":"ItemNodePresenter.AddItem wraps any exception thrown by the underlying Quantum collection node (Container.IndexedTarget(Index).Add(value)) in a NodePresenterException with this generic message. The library does this so that all node-mutation failures surface through a single exception type in the presenter layer; the real cause is always in InnerException. Typical inner causes are type-incompatible values, read-only or fixed-size collections, or collection mutations rejected by property setters/validators.","triggerScenarios":"Calling ItemNodePresenter.AddItem(value) when the target collection at Index rejects the add: adding an object whose type is not assignable to the collection's element type, adding to a fixed-size array or read-only list, or the collection's Add helper (e.g. reflection-based invoke) throwing (TargetException/ArgumentException/TargetInvocationException from the wrapped list).","commonSituations":"Editor property-grid plugins that push items of the wrong element type into a list; modifying collections of structs/arrays that do not support Add; a model property changed to a read-only collection type after a version upgrade; invoking the command from a non-UI thread while the node graph is being rebuilt (IndexedTarget returns a different or disposed node).","solutions":["Catch NodePresenterException and inspect InnerException to see the real failure (type mismatch, read-only collection, etc.).","Verify the value's runtime type is assignable to the collection's element type before calling AddItem (use the node's Descriptor / GetInnerCollectionType).","Confirm the node is actually a mutable collection: check Container.IndexedTarget(Index)?.IsEnumerable == true and that the collection type supports Add (not an array).","Ensure all mutations run on the UI thread / same node instance the presenter was created with; refresh the presenter if the underlying object was replaced."],"exampleFix":"// before\nitemPresenter.AddItem(someString); // list of int -> ArgumentException wrapped in NodePresenterException\n// after\nif (itemPresenter.Type.IsInstanceOfType(someString))\n    itemPresenter.AddItem(someString);\nelse\n    logger.Warn($\"Cannot add {someString.GetType()} to collection of {itemPresenter.Type}\");","handlingStrategy":"try-catch","validationCode":"var target = presenter.Container.IndexedTarget(presenter.Index);\nif (target == null || !target.IsEnumerable)\n    throw new InvalidOperationException(\"Node is not a mutable collection.\");\nif (!presenter.Type.IsInstanceOfType(value))\n    throw new ArgumentException($\"{value.GetType()} is not assignable to {presenter.Type}\");","typeGuard":"static bool CanAddItem(ItemNodePresenter p, object value)\n    => p.Container.IndexedTarget(p.Index)?.IsEnumerable == true\n       && p.Type.IsInstanceOfType(value);","tryCatchPattern":"try\n{\n    itemPresenter.AddItem(value);\n}\ncatch (NodePresenterException ex)\n{\n    logger.Error(ex, \"Add failed on {Node}\", itemPresenter.Path); // root cause: ex.InnerException\n    // surface ex.InnerException.Message to the user / roll back UI state\n}","preventionTips":["Always check IsEnumerable and element-type compatibility before mutating collection nodes.","Treat NodePresenterException.InnerException as the real error and log it, not the outer message.","Keep model members as List<T>/Dictionary<K,V> (not arrays) so Quantum's Add path works.","Perform all node mutations on the UI thread to avoid racing with presenter rebuilds."],"tags":["dotnet","stride","quantum","collection","wrapped-exception"],"backgroundTag":"unsupported-operation","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"}