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
- Inspect and break the logical-tree cycle: ensure no element's parent chain loops back on itself
- Set parents only via legal APIs (adding to a Panel, setting Content) rather than manually mutating parent references
- Break very deep trees into separate trees or resolve resources explicitly via FindResource on a nearer element
- 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
- Never mutate Parent/parent references manually
- Build trees via Content/Children APIs only
- Add cycle detection in code that constructs logical trees programmatically
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
- ' ' must be the root element of a tree, but has a logical…
- SR.CannotBeSelfParent
- SR.CannotBeSelfParent
- SR.CannotBeSelfParent
- SR.CannotModifyLogicalChildrenDuringTreeWalk
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)