{"record":{"id":"6375a6331d1cc50b","repo":"dotnet/wpf","slug":"sr-relativesourceinvalidancestorlevel","errorCode":null,"errorMessage":"SR.RelativeSourceInvalidAncestorLevel","messagePattern":"SR\\.RelativeSourceInvalidAncestorLevel","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/RelativeSource.cs","lineNumber":218,"sourceCode":"        /// setting AncestorLevel will implicitly lock Mode to FindAncestor. </remarks>\n        /// <exception cref=\"InvalidOperationException\"> RelativeSource is not in FindAncestor mode </exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"> AncestorLevel cannot be set to less than 1 </exception>\n        public int AncestorLevel\n        {\n            get { return _ancestorLevel; }\n            set\n            {\n                Debug.Assert((!IsUninitialized) || (_mode == RelativeSourceMode.FindAncestor));\n\n                if (_mode != RelativeSourceMode.FindAncestor)\n                {\n                    // in all other modes, AncestorLevel should not get set to a non-zero value\n                    if (value != 0)\n                        throw new InvalidOperationException(SR.RelativeSourceNotInFindAncestorMode);\n                }\n                else if (value < 1)\n                {\n                    throw new ArgumentOutOfRangeException(SR.RelativeSourceInvalidAncestorLevel);\n                }\n                else\n                {\n                    _ancestorLevel = value;\n                }\n            }\n        }\n\n        /// <summary>\n        /// This method is used by TypeDescriptor to determine if this property should\n        /// be serialized.\n        /// </summary>\n        [EditorBrowsable(EditorBrowsableState.Never)]\n        public bool ShouldSerializeAncestorLevel()\n        {\n            return (_mode == RelativeSourceMode.FindAncestor);\n        }\n","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/RelativeSource.cs#L200-L236","documentation":"Assigning an AncestorLevel less than 1 to a RelativeSource throws ArgumentOutOfRangeException. AncestorLevel counts ancestor levels (1 = nearest ancestor), so 0 or negative levels are meaningless in FindAncestor mode and the setter treats them as an invalid argument.","triggerScenarios":"Setting RelativeSource.AncestorLevel to 0 or a negative value while _mode == FindAncestor (note: 0 is allowed only to clear it in non-FindAncestor modes).","commonSituations":"Computed level expressions evaluating to 0; XAML AncestorLevel=\"0\"; loop counters that decrement below 1 when climbing ancestors.","solutions":["Use AncestorLevel >= 1 in FindAncestor mode","Clamp computed levels with Math.Max(1, level)","Use AncestorType=null semantics instead of 0 if you meant 'no restriction'"],"exampleFix":"// before\nrs.AncestorLevel = 0; // throws in FindAncestor mode\n// after\nrs.AncestorLevel = 1;","handlingStrategy":"validation","validationCode":"int lvl = Math.Max(1, computedLevel);\nrs.AncestorLevel = lvl;","typeGuard":null,"tryCatchPattern":"try { rs.AncestorLevel = n; }\ncatch (ArgumentOutOfRangeException) { rs.AncestorLevel = 1; }","preventionTips":["Clamp AncestorLevel to >= 1","Avoid AncestorLevel=\"0\" in FindAncestor XAML","Guard computed levels against underflow"],"tags":["wpf","data-binding","relativesource","argument-out-of-range"],"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"}