{"record":{"id":"44557d02548e4d3e","repo":"dotnet/wpf","slug":"sr-stylecannotbebasedonself","errorCode":null,"errorMessage":"SR.StyleCannotBeBasedOnSelf","messagePattern":"SR\\.StyleCannotBeBasedOnSelf","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Style.cs","lineNumber":205,"sourceCode":"\n                return _basedOn;\n            }\n            set\n            {\n                // Verify Context Access\n                VerifyAccess();\n\n                if (_sealed)\n                {\n                    throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, \"Style\"));\n                }\n\n                if( value == this )\n                {\n                    // Basing on self is not allowed.  This is a degenerate case\n                    //  of circular reference chain, the full check for circular\n                    //  reference is done in Seal().\n                    throw new ArgumentException(SR.StyleCannotBeBasedOnSelf);\n                }\n\n                _basedOn = value;\n\n                SetModified(BasedOnID);\n            }\n        }\n\n\n        /// <summary>\n        ///     Visual triggers\n        /// </summary>\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]\n        public TriggerCollection Triggers\n        {\n            get\n            {\n                // Verify Context Access","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Style.cs#L187-L223","documentation":"The Style.BasedOn setter throws ArgumentException (SR.StyleCannotBeBasedOnSelf) when a style is assigned as its own BasedOn. This is a degenerate circular-reference case that would produce infinite lookup during style resolution.","triggerScenarios":"Executing style.BasedOn = style; — typically via a code path that computes the base style from a dictionary and accidentally selects the same instance (e.g. self-referencing keyed resource lookup).","commonSituations":"Programmatic style chains where the lookup key resolves back to the same style; refactoring XAML BasedOn={StaticResource SameKey} onto itself; copy-paste of style definitions keeping the same key.","solutions":["Assign a different Style instance as BasedOn; verify the resource key used to fetch the base style is not the style's own key.","If creating a default-derived style, pass null (leave BasedOn unset) to inherit from the theme default.","Add a guard comparing references before assignment when base styles are computed dynamically."],"exampleFix":"// before\nstyle.BasedOn = style; // circular\n// after\nvar baseStyle = (Style)resources[\"BaseButtonStyle\"];\nif (!ReferenceEquals(baseStyle, style)) style.BasedOn = baseStyle;","handlingStrategy":"validation","validationCode":"if (!ReferenceEquals(baseStyle, style)) style.BasedOn = baseStyle; else throw new InvalidOperationException(\"Style cannot be based on itself\");","typeGuard":"static bool CanBaseOn(Style style, Style baseStyle) => !ReferenceEquals(style, baseStyle);","tryCatchPattern":"try { style.BasedOn = candidate; }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"based on itself\")) { /* resolve the correct base key or leave BasedOn unset */ }","preventionTips":["Verify resource keys so a style never resolves its own key as its base.","When computing base styles dynamically, compare references before assignment.","Model style inheritance chains as a DAG and check for cycles when building them programmatically."],"tags":["invalid-argument-value","circular-reference","style","wpf"],"backgroundTag":"invalid-argument-value","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"}