AvaloniaUI/Avalonia · error · InvalidOperationException

Child styles must have a selector.

Error message

Child styles must have a selector.

What it means

Thrown by Style.SetParent when the new parent is a Style that itself has a Selector, but the child Style's Selector is null. A style nested under another (selector-bearing) style must carry its own selector to express what it matches relative to the parent; a selector-less child is invalid in that position.

Source

Thrown at src/Avalonia.Base/Styling/Style.cs:50

        /// </summary>
        public Selector? Selector 
        {
            get => _selector;
            set => _selector = ValidateSelector(value);
        }

        /// <summary>
        /// Returns a string representation of the style.
        /// </summary>
        /// <returns>A string representation of the style.</returns>
        public override string ToString() => Selector?.ToString(this) ?? "Style";

        internal override void SetParent(StyleBase? parent)
        {
            if (parent is Style parentStyle && parentStyle.Selector is not null)
            {
                if (Selector is null)
                    throw new InvalidOperationException("Child styles must have a selector.");
                Selector.ValidateNestingSelector(false);
            }
            else if (parent is ControlTheme)
            {
                if (Selector is null)
                    throw new InvalidOperationException("Child styles must have a selector.");
                Selector.ValidateNestingSelector(true);
            }

            base.SetParent(parent);
        }

        internal SelectorMatchResult TryAttach(StyledElement target, object? host, FrameType type)
        {
            _ = target ?? throw new ArgumentNullException(nameof(target));

            var result = SelectorMatchResult.NeverThisType;

View on GitHub (pinned to 11c5427268)

Solutions

  1. Give the child style a Selector (typically starting with `^` for nesting), e.g. `new Style(s => s.Nesting().Class("foo"))`.
  2. If the child is only for resources/setters shared unconditionally, put it under a ControlTheme or top-level context instead of under a selector-bearing Style.
  3. In AXAML, ensure every nested `<Style>` has a `Selector` attribute.

Example fix

// before
var parent = new Style(s => s.OfType<Button>());
parent.Children.Add(new Style()); // no Selector

// after
parent.Children.Add(new Style(s => s.Nesting().Class("pointerover")));
Defensive patterns

Strategy: validation

Validate before calling

if (parent is Style ps && ps.Selector is not null && childStyle.Selector is null)
    throw new InvalidOperationException("Child style under a selector-bearing Style must have its own Selector.");

Type guard

static bool ChildHasSelector(Style child) => child.Selector is not null;

Prevention

When it happens

Trigger: Adding a `new Style()` (no Selector) as a child of a Style that has a Selector. Parenting happens when the child is added to the parent's Children or when the style tree is assembled.

Common situations: Using a child Style as a mere container for setters/resources without intending it to match, under a selector-bearing parent; refactoring that stripped a child's Selector; AXAML nested `<Style>` without a Selector inside a selector-bearing `<Style>`.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/ed1e61f941be23f9. Report an issue: GitHub.