stride3d/stride · error · InvalidOperationException

is not a descendant of UIElement.

Error message

{uiElementType} is not a descendant of UIElement.

What it means

Thrown by RendererManager.RegisterRendererFactory when the registered uiElementType is not assignable from UIElement (i.e. it is not a UIElement descendant). The renderer lookup walks the element's type hierarchy expecting UIElement-derived types; registering an unrelated type would never match and indicates a caller mistake, so it throws InvalidOperationException naming the offending type.

Solutions

  1. Only pass types that derive (directly or transitively) from Stride.UI.UIElement to RegisterRendererFactory.
  2. If the type comes from reflection, generics or assembly scanning, filter candidates with typeof(UIElement).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()) before registering.
  3. Fix misconfigured generic type arguments or scanned assemblies so non-UIElement types never reach the registration call.
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at sources/engine/Stride.UI/Renderers/RendererManager.cs:68 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at sources/engine/Stride.UI/Renderers/RendererManager.cs:68

                    elementRenderer = defaultFactory.TryCreateRenderer(element);

                if (elementRenderer == null)
                    throw new InvalidOperationException($"No renderer found for element {element}");

                // cache the renderer for future uses.
                elementIdToRenderer[element.Id] = elementRenderer;
            }

            return elementRenderer;
        }

        public void RegisterRendererFactory(Type uiElementType, IElementRendererFactory factory)
        {
            if (uiElementType == null) throw new ArgumentNullException(nameof(uiElementType));
            if (factory == null) throw new ArgumentNullException(nameof(factory));

            if (!typeof(UIElement).GetTypeInfo().IsAssignableFrom(uiElementType.GetTypeInfo()))
                throw new InvalidOperationException(uiElementType + " is not a descendant of UIElement.");

            typesToUserFactories[uiElementType] = factory;
        }

        public void RegisterRenderer(UIElement element, ElementRenderer renderer)
        {
            if (element == null) throw new ArgumentNullException(nameof(element));
            if (renderer == null) throw new ArgumentNullException(nameof(renderer));

            elementIdToRenderer[element.Id] = renderer;
        }

        public void Dispose()
        {
            foreach (var renderer in elementIdToRenderer.Values)
            {
                if (!renderer.IsDisposed)
                    renderer.Dispose();

View on GitHub (pinned to 96fad776d2)