AvaloniaUI/Avalonia · error · InvalidOperationException

PropertySet depth limit reached

Error message

PropertySet depth limit reached

What it means

PropertySet snapshots cap nesting at one level: Snapshot() starts SnapshotCore(1), and each nested CompositionPropertySet decrements the budget. Reaching zero budget throws InvalidOperationException to keep the serialized expression parameter graph shallow and bounded.

Source

Thrown at src/Avalonia.Base/Rendering/Composition/CompositionPropertySet.cs:126

        internal void Clear(string key)
        {
            _objects.Remove(key);
            _variants.Remove(key);
        }

        internal PropertySetSnapshot Snapshot() =>
            SnapshotCore(1);
        
        private PropertySetSnapshot SnapshotCore(int allowedNestingLevel)
        {
            var dic = new Dictionary<string, PropertySetSnapshot.Value>(_objects.Count + _variants.Count);
            foreach (var o in _objects)
            {
                if (o.Value is CompositionPropertySet ps)
                {
                    if (allowedNestingLevel <= 0)
                        throw new InvalidOperationException("PropertySet depth limit reached");
                    dic[o.Key] = new PropertySetSnapshot.Value(ps.SnapshotCore(allowedNestingLevel - 1));
                }
                else if (o.Value.Server == null)
                    throw new InvalidOperationException($"Object of type {o.Value.GetType()} is not allowed");
                else
                    dic[o.Key] = new PropertySetSnapshot.Value((ServerObject)o.Value.Server);
            }

            foreach (var v in _variants)
                dic[v.Key] = v.Value;
            
            return new PropertySetSnapshot(dic);
        }
    }

    public enum CompositionGetValueStatus
    {
        Succeeded,

View on GitHub (pinned to 11c5427268)

Solutions

  1. Flatten your parameter data: keep only a single level of nested CompositionPropertySet at most.
  2. Store primitive values (scalars/vectors) directly instead of nesting PropertySets.
  3. Reference CompositionObjects directly via SetReferenceParameter rather than wrapping them in nested PropertySets.

Example fix

// before
var inner = compositor.CreatePropertySet();
var middle = compositor.CreatePropertySet();
middle.Set("child", inner);
var outer = compositor.CreatePropertySet();
outer.Set("m", middle); // depth 2 -> Snapshot throws

// after
// flatten: put the values directly in one property set
outer.InsertScalar("v", 42);
Defensive patterns

Strategy: validation

Validate before calling

// Enforce a single nesting level before adding nested property sets.
if (nestingDepth > 1) throw new InvalidOperationException("PropertySet nesting exceeds 1 level");

Prevention

When it happens

Trigger: Inserting a CompositionPropertySet that itself contains another CompositionPropertySet into a property set, then taking a snapshot (which happens when an animation referencing such parameters is started).

Common situations: Building nested PropertySet structures for expression parameters; chaining reference parameters through multiple property sets, which the composition API explicitly does not support (see the 'we DON'T support expression paths' comment in the source).

Related errors


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