stride3d/stride · error · InvalidOperationException

Can only assign UIElementService to the root element!

Error message

Can only assign UIElementService to the root element!

What it means

The UIElementServices property may only be set on the root element of a UI tree. Stride throws InvalidOperationException if a non-root element (one that already has a Parent) is assigned services, because service resolution flows from the root down and per-node assignment would break that invariant.

Solutions

  1. Assign UIElementServices only on the root element (e.g. the page or root UIComponent element) before/while building the tree.
  2. Set the property before adding the element as a child of another element.
  3. Let child elements inherit services from the root instead of assigning directly.

Example fix

// before
foreach (var el in page.Traverse()) el.UIElementServices = services; // throws on children
// after
root.UIElementServices = services; // root only; children inherit
Defensive patterns

Strategy: validation

Validate before calling

if (element.Parent == null)
    element.UIElementServices = services;
else
    element.FindRoot()?.UIElementServices = services;

Type guard

bool IsRoot(UIElement e) => e.Parent == null;

Try / catch

try { element.UIElementServices = services; }
catch (InvalidOperationException) { element.FindRoot().UIElementServices = services; }

Prevention

When it happens

Trigger: Setting element.UIElementServices = services on a child element whose Parent is already set; assigning services after the element has been added to a UI tree.

Common situations: Looping over all elements in a page and assigning services to each; re-parenting an element then trying to give it its own services instance.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.UI/UIElement.cs:649

                    child.LayoutingContext = value;
            }
        }

        private UIElementServices uiElementServices;

        internal UIElementServices UIElementServices
        {
            get
            {
                if (Parent != null && !Parent.UIElementServices.Equals(ref uiElementServices))
                    uiElementServices = Parent.UIElementServices;

                return uiElementServices;
            }
            set
            {
                if (Parent != null)
                    throw new InvalidOperationException("Can only assign UIElementService to the root element!");

                uiElementServices = value;
            }
        }

        /// <summary>
        /// The visual children of this element.
        /// </summary>
        /// <remarks>If the class is inherited it is the responsibility of the descendant class to correctly update this collection</remarks>
        [DataMemberIgnore]
        protected internal UIElementCollection VisualChildrenCollection { get; }

        /// <summary>
        /// Invalidates the arrange state (layout) for the element.
        /// </summary>
        protected internal void InvalidateArrange()
        {
            ForceArrange(); // force arrange on top hierarchy

View on GitHub (pinned to 96fad776d2)