stride3d/stride · error · InvalidOperationException

Cannot add a null UIElement to the children list.

Error message

Cannot add a null UIElement to the children list.

What it means

Panel.OnLogicalChildAdded rejects null children with InvalidOperationException, because a null child would corrupt the parent/visual-parent links, sorting, and world-matrix arrays that Panel maintains for its children.

Solutions

  1. Filter null elements before adding to Children (use AddRange on a filtered list)
  2. Fix the data source so items are never null (null-check models during binding)
  3. If a child failed to construct, skip it or substitute a placeholder element instead of adding null

Example fix

// before
foreach (var item in items)
    panel.Children.Add(CreateChild(item)); // CreateChild may return null
// after
foreach (var item in items)
{
    var child = CreateChild(item);
    if (child != null)
        panel.Children.Add(child);
}
Defensive patterns

Strategy: validation

Validate before calling

var validChildren = items.Select(CreateChild).Where(c => c != null);
foreach (var child in validChildren) panel.Children.Add(child);

Type guard

static bool IsValidChild(UIElement el) => el != null;

Try / catch

try { panel.Children.Add(child); }
catch (InvalidOperationException ex) when (ex.Message.Contains("null UIElement")) { logger.LogWarning("Skipped null child element"); }

Prevention

When it happens

Trigger: Adding null to a panel's Children collection (e.g. panel.Children.Add(null)) or inserting null via a collection initializer / deserializer, which triggers LogicalChildrenChanged and then OnLogicalChildAdded.

Common situations: UI built from data where an item is null (missing model binding); deserializing a UI layout file containing a null node; LINQ producing null entries that get bulk-added.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.UI/Panels/Panel.cs:159

        {
            if (oldElement.Parent == null)
                throw new UIInternalException("The parent of the removed children UIElement not null");
            SetParent(oldElement, null);
            SetVisualParent(oldElement, null);

            if (oldElement.MouseOverState != MouseOverState.MouseOverNone)
                MouseOverState = MouseOverState.MouseOverNone;
        }

        /// <summary>
        /// Action to perform when a logical child is added.
        /// </summary>
        /// <param name="newElement">The element that has been added</param>
        /// <param name="index">The index in the collection where the child has been added</param>
        protected virtual void OnLogicalChildAdded(UIElement newElement, int index)
        {
            if (newElement == null)
                throw new InvalidOperationException("Cannot add a null UIElement to the children list.");
            SetParent(newElement, this);
            SetVisualParent(newElement, this);
            VisualChildrenCollection.Sort(PanelChildrenSorter);
            if (Children.Count > childrenArrangeWorldMatrix.Length)
                childrenArrangeWorldMatrix = new Matrix[2 * Children.Count];
        }

        protected override void UpdateWorldMatrix(ref Matrix parentWorldMatrix, bool parentWorldChanged)
        {
            var shouldUpdateAllChridrenMatrix = parentWorldChanged || ArrangeChanged || LocalMatrixChanged;

            base.UpdateWorldMatrix(ref parentWorldMatrix, parentWorldChanged);

            var childIndex = 0;
            foreach (var child in VisualChildrenCollection)
            {
                var shouldUpdateChildWorldMatrix = shouldUpdateAllChridrenMatrix || childrenWithArrangeMatrixInvalidated.Contains(child);
                {

View on GitHub (pinned to 96fad776d2)