dotnet/wpf · error · InvalidOperationException

SR.LogicalTreeLoop

Error message

SR.LogicalTreeLoop

What it means

During FindResource resource lookup, WPF walks the logical tree upward. If the walk exceeds ContextLayoutManager.s_LayoutRecursionLimit (MAX_TREE_DEPTH), a loop in the logical tree is suspected and InvalidOperationException(SR.LogicalTreeLoop) is thrown. The library throws this to prevent stack overflow from a cyclic parent chain.

Solutions

  1. Inspect and break the logical-tree cycle: ensure no element's parent chain loops back on itself
  2. Set parents only via legal APIs (adding to a Panel, setting Content) rather than manually mutating parent references
  3. Break very deep trees into separate trees or resolve resources explicitly via FindResource on a nearer element
  4. For programmatic graphs, add your own depth guard before inserting nodes

Example fix

// before
child.Parent = parent; parent.Parent = child; // cycle
// after
// build a tree: only parent -> child links, no cycles
parent.Children.Add(child);
Defensive patterns

Strategy: try-catch

Validate before calling

// Walk parents yourself with a depth cap before calling FindResource
int depth = 0; DependencyObject d = element;
while ((d = LogicalTreeHelper.GetParent(d) ?? (d as FrameworkContentElement)?.Parent) != null) if (++depth > 200) throw new InvalidOperationException("logical tree loop");

Try / catch

try { var res = element.FindResource(key); }
catch (InvalidOperationException) { res = Application.Current.TryFindResource(key); }

Prevention

When it happens

Trigger: Calling FindResource/TryFindResource (or resolving a DynamicResource) on an element whose logical-parent chain forms a cycle, or a tree deeper than the layout recursion limit.

Common situations: Accidentally setting LogicalParent in a loop in custom code; cyclic object graphs built programmatically; extremely deep generated trees (rare) exceeding the depth limit during resource resolution.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/3dd8d04466372931. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElement.cs:1173

            FrameworkObject fo = startNode;
            object value;
            Style style;
            FrameworkTemplate frameworkTemplate;
            Style themeStyle;
            int loopCount = 0;
            bool hasParent = true;
            inheritanceBehavior = InheritanceBehavior.Default;

            while (hasParent)
            {
                Debug.Assert(startNode.IsValid || unlinkedParent != null,
                              "Don't call FindResource with a null fe/fce and unlinkedParent");

                if (loopCount > ContextLayoutManager.s_LayoutRecursionLimit)
                {
                    // We suspect a loop here because the loop count
                    // has exceeded the MAX_TREE_DEPTH expected
                    throw new InvalidOperationException(SR.LogicalTreeLoop);
                }
                else
                {
                    loopCount++;
                }

                // -------------------------------------------
                //  Lookup ResourceDictionary on the current instance
                // -------------------------------------------

                style = null;
                frameworkTemplate = null;
                themeStyle = null;

                if (fo.IsFE)
                {
                    FrameworkElement fe = fo.FE;

View on GitHub (pinned to 81131a70a4)