AvaloniaUI/Avalonia · error · InvalidOperationException

Styles can only be applied to AvaloniaObjects.

Error message

Styles can only be applied to AvaloniaObjects.

What it means

Thrown by StyleBase.Attach when applying a StyleInstance to a target element. Attach receives a StyledElement and asserts it is an AvaloniaObject. Because StyledElement derives from Animatable which derives from AvaloniaObject, the C# type system already guarantees this for any non-null instance, so the runtime check exists as a defensive invariant: it fires only when target is null or when Attach is reached through non-type-safe paths (reflection, IL weaving, corrupted runtime state).

Source

Thrown at src/Avalonia.Base/Styling/StyleBase.cs:117

                for (var i = 0; i < _children.Count; ++i)
                {
                    if (_children[i].TryGetResource(key, themeVariant, out result))
                        return true;
                }
            }

            result= null;
            return false;
        }

        internal ValueFrame Attach(
            StyledElement target,
            IStyleActivator? activator,
            FrameType type,
            bool canShareInstance)
        {
            if (target is not AvaloniaObject ao)
                throw new InvalidOperationException("Styles can only be applied to AvaloniaObjects.");

            StyleInstance instance;

            if (_sharedInstance is not null && canShareInstance)
            {
                instance = _sharedInstance;
            }
            else
            {
                canShareInstance &= activator is null;

                instance = new StyleInstance(this, activator, type);

                if (_setters is not null)
                {
                    foreach (var setter in _setters)
                    {
                        var setterInstance = setter.Instance(instance, target);

View on GitHub (pinned to 11c5427268)

Solutions

  1. If you are calling Attach via reflection, stop: use the public styling surface (Styles.Add on a control's or Application's Styles collection).
  2. If the error appears during normal styling, capture a stack trace and confirm the StyledElement being styled is non-null at match time; a null target here usually means a control was detached/collected while a style frame was still being attached.
  3. Treat this as a framework-bug signal if reached through public API and file an issue with the repro.

Example fix

// before
style.Attach(nullElement, activator, type, canShareInstance); // nullElement is null

// after
if (target is AvaloniaObject) style.Attach(target, activator, type, canShareInstance);
Defensive patterns

Strategy: validation

Validate before calling

// Guard before invoking Attach-equivalent logic: confirm non-null and AvaloniaObject-derived.
if (target is null || target is not AvaloniaObject)
{
    // skip attaching; log target identity for diagnosis
    return;
}

Type guard

// C# narrowing: StyledElement already guarantees AvaloniaObject, so guard mainly against null.
static bool IsValidStyleTarget(StyledElement? target) => target is AvaloniaObject;

Prevention

When it happens

Trigger: Attach is internal and invoked by the styling system during selector matching. The throw is reached when (a) a null StyledElement is passed to Attach, or (b) Attach is invoked via reflection/dynamic dispatch with an argument whose runtime type is not AvaloniaObject. Neither path is reachable through the public Styles/Control.Styles API under normal compilation.

Common situations: Reflection-based or code-generation styling frameworks that bypass the public API; AOT/trimmer scenarios that strip AvaloniaObject base metadata; a null control reference surviving into the style-application phase (e.g. a selector matching an element that has since been detached and nulled); custom IStyleInstance implementations that fabricate an Attach call.

Related errors


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