{"record":{"id":"4d809fbb53a3df17","repo":"dotnet/wpf","slug":"sr-format-sr-layoutmanager-deeprecursion-treelevellimit","errorCode":null,"errorMessage":"SR.Format(SR.LayoutManager_DeepRecursion, TreeLevelLimit)","messagePattern":"SR\\.Format\\(SR\\.LayoutManager_DeepRecursion, TreeLevelLimit\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs","lineNumber":2733,"sourceCode":"        }\n\n        //This is used by LayoutManager as a perf optimization for layout updates.\n        //During layout updates, LM needs to find which areas of the visual tree\n        //are higher in the tree - they have to be processed first to avoid multiple\n        //updates of lower descendants. The tree level counter is maintained by\n        //UIElement.PropagateResume/SuspendLayout methods and uses 8 bits in VisualFlags to\n        //keep the count.\n        internal uint TreeLevel\n        {\n            get\n            {\n                return ((uint)_flags & 0xFFE00000) >> 21;\n            }\n            set\n            {\n                if(value > TreeLevelLimit)\n                {\n                    throw new InvalidOperationException(SR.Format(SR.LayoutManager_DeepRecursion, TreeLevelLimit));\n                }\n\n                _flags = (VisualFlags)(((uint)_flags & 0x001FFFFF) | (value << 21));\n            }\n        }\n\n\n        #endregion VisualChildren\n\n\n        #region VisualParent\n\n        /// <summary>\n        /// Returns the parent of this Visual.  Parent may be either a Visual or Visual3D.\n        /// </summary>\n        protected DependencyObject VisualParent\n        {\n            get","sourceCodeStart":2715,"sourceCodeEnd":2751,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs#L2715-L2751","documentation":"Visual.TreeLevel limits the visual tree depth to TreeLevelLimit (about 2047 levels, stored in flag bits). Setting it beyond the limit throws InvalidOperationException(LayoutManager_DeepRecursion), preventing stack overflow during recursive layout/visual-tree traversal.","triggerScenarios":"Building or embedding a visual tree deeper than TreeLevelLimit; programmatically adding nested visuals in an unbounded recursive structure.","commonSituations":"Recursive data-bound templates with cyclic or self-referencing data; pathological nested layouts generated from recursive algorithms.","solutions":["Flatten or restructure the visual tree to reduce depth","Detect and break cycles in data/templates driving recursive nesting","Use non-visual data structures (e.g. virtualization/ItemsControl) instead of deep visual nesting"],"exampleFix":"// before\nVisual current = root;\nfor (int i = 0; i < 5000; i++) { var v = new Border(); current.AddVisualChild(v); current = v; }\n// after\nvar items = new ItemsControl { ItemsSource = Enumerable.Range(0, 5000) }; // flat, virtualized","handlingStrategy":"validation","validationCode":"int Depth(Visual v) { int d = 0; for (DependencyObject p = v; p != null; p = VisualTreeHelper.GetParent(p)) d++; return d; } // ensure < ~2047","typeGuard":"bool DepthWithinLimit(Visual v) => Depth(v) < 2000;","tryCatchPattern":"try { /* build tree */ } catch (InvalidOperationException ex) when (ex.Message.Contains(\"recursion\") || ex.Message.Contains(\"deep\")) { /* flatten tree */ }","preventionTips":["Avoid unbounded recursive visual nesting","Break data/template cycles driving recursion","Use virtualization for deep data"],"tags":["wpf","visual-tree","recursion-limit"],"backgroundTag":"value-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}