stride3d/stride · error · NodePresenterException

An error occurred while adding an item to the node, see the

Error message

An error occurred while adding an item to the node, see the inner exception for more information.

What it means

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.

Solutions

  1. Catch NodePresenterException and inspect InnerException to see the real failure (type mismatch, read-only collection, etc.).
  2. Verify the value's runtime type is assignable to the collection's element type before calling AddItem (use the node's Descriptor / GetInnerCollectionType).
  3. Confirm the node is actually a mutable collection: check Container.IndexedTarget(Index)?.IsEnumerable == true and that the collection type supports Add (not an array).
  4. 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.

Example fix

// before
itemPresenter.AddItem(someString); // list of int -> ArgumentException wrapped in NodePresenterException
// after
if (itemPresenter.Type.IsInstanceOfType(someString))
    itemPresenter.AddItem(someString);
else
    logger.Warn($"Cannot add {someString.GetType()} to collection of {itemPresenter.Type}");
Defensive patterns

Strategy: try-catch

Validate before calling

var target = presenter.Container.IndexedTarget(presenter.Index);
if (target == null || !target.IsEnumerable)
    throw new InvalidOperationException("Node is not a mutable collection.");
if (!presenter.Type.IsInstanceOfType(value))
    throw new ArgumentException($"{value.GetType()} is not assignable to {presenter.Type}");

Type guard

static bool CanAddItem(ItemNodePresenter p, object value)
    => p.Container.IndexedTarget(p.Index)?.IsEnumerable == true
       && p.Type.IsInstanceOfType(value);

Try / catch

try
{
    itemPresenter.AddItem(value);
}
catch (NodePresenterException ex)
{
    logger.Error(ex, "Add failed on {Node}", itemPresenter.Path); // root cause: ex.InnerException
    // surface ex.InnerException.Message to the user / roll back UI state
}

Prevention

When it happens

Trigger: 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).

Common situations: 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).

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/6ec43e58d82d2b67. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Quantum/Presenters/ItemNodePresenter.cs:84

        }
        catch (Exception e)
        {
            throw new NodePresenterException("An error occurred while updating the value of the node, see the inner exception for more information.", e);
        }
    }

    public override void AddItem(object value)
    {
        if (Container.IndexedTarget(Index)?.IsEnumerable != true)
            throw new NodePresenterException($"{nameof(MemberNodePresenter)}.{nameof(AddItem)} cannot be invoked on members that are not collection.");

        try
        {
            Container.IndexedTarget(Index).Add(value);
        }
        catch (Exception e)
        {
            throw new NodePresenterException("An error occurred while adding an item to the node, see the inner exception for more information.", e);
        }
    }

    public override void AddItem(object value, NodeIndex index)
    {
        if (Container.IndexedTarget(Index)?.IsEnumerable != true)
            throw new NodePresenterException($"{nameof(MemberNodePresenter)}.{nameof(AddItem)} cannot be invoked on members that are not collection.");

        try
        {
            Container.IndexedTarget(Index).Add(value, index);
        }
        catch (Exception e)
        {
            throw new NodePresenterException("An error occurred while adding an item to the node, see the inner exception for more information.", e);
        }
    }

View on GitHub (pinned to 96fad776d2)