{"record":{"id":"22af2762bd394757","repo":"dotnet/wpf","slug":"sr-format-sr-cyclicthemestylereferencedetected-this","errorCode":null,"errorMessage":"SR.Format(SR.CyclicThemeStyleReferenceDetected, this)","messagePattern":"SR\\.Format\\(SR\\.CyclicThemeStyleReferenceDetected, this\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkContentElement.cs","lineNumber":659,"sourceCode":"                    if (toolTip != null)\n                    {\n                        FrameworkObject toolTipFO = new FrameworkObject(toolTip);\n                        if (toolTipFO.IsValid)\n                        {\n                            TreeWalkHelper.InvalidateOnResourcesChange(toolTipFO.FE, toolTipFO.FCE, ResourcesChangeInfo.ThemeChangeInfo);\n                        }\n                    }\n\n                    OnThemeChanged();\n                }\n                finally\n                {\n                    IsThemeStyleUpdateInProgress = false;\n                }\n            }\n            else\n            {\n                throw new InvalidOperationException(SR.Format(SR.CyclicThemeStyleReferenceDetected, this));\n            }\n        }\n\n        // Called when the theme changes so resources not in the tree can be updated by subclasses\n        internal virtual void OnThemeChanged()\n        {\n        }\n\n        ///<summary>\n        ///     Initiate the processing for Loaded event broadcast starting at this node\n        /// </summary>\n        /// <remarks>\n        ///     This method is to allow firing Loaded event from a Helper class since the override is protected\n        /// </remarks>\n        internal void FireLoadedOnDescendentsInternal()\n        {\n            // This is to prevent duplicate Broadcasts for the Loaded event\n            if (LoadedPending == null)","sourceCodeStart":641,"sourceCodeEnd":677,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkContentElement.cs#L641-L677","documentation":"FrameworkElement/FrameworkContentElement.UpdateThemeStyleProperty detects that the ThemeStyleProperty update is re-entered while an update is already in progress, indicating a theme style whose setter/reference chain points back to the same element, creating a cycle. WPF throws InvalidOperationException to break infinite recursion during theme style invalidation.","triggerScenarios":"UpdateThemeStyleProperty is called (via OnInitialized or OnResourcesChanged) with IsThemeStyleUpdateInProgress already true, i.e. the theme style lookup for the element triggers another theme style invalidation of the same element before the first completes.","commonSituations":"A custom control's theme style (or a BasedOn chain) triggers resource changes that re-invoke OnResourcesChanged on the same element; overriding OnInitialized/OnThemeChanged in a way that re-fetches the theme style; DynamicResource references inside the theme style that resolve back to the element.","solutions":["Inspect the element's theme style and any BasedOn chain for references (DynamicResource, template bindings) that point back to the element and break the cycle.","Remove or defer code in OnInitialized/OnResourcesChanged overrides that changes resources or re-applies the theme style during initialization.","Ensure DefaultStyleKey/Style overrides are constant per type and not changed in response to style or resource invalidation.","If caught at runtime, log the element type and style keys; the InvalidOperationException message includes the offending element."],"exampleFix":"// before\nprotected override void OnResourcesChanged(DependencyObject d, EventArgs e)\n{\n    base.OnResourcesChanged(d, e);\n    this.SetResourceReference(StyleProperty, MyStyleKey); // re-triggers theme style update during update\n}\n\n// after\nprotected override void OnResourcesChanged(DependencyObject d, EventArgs e)\n{\n    base.OnResourcesChanged(d, e);\n    if (!IsThemeStyleUpdateInProgress)\n    {\n        Dispatcher.BeginInvoke(() => this.SetResourceReference(StyleProperty, MyStyleKey));\n    }\n}","handlingStrategy":"validation","validationCode":"if (element.IsThemeStyleUpdateInProgress)\n    throw new InvalidOperationException(\"Theme style update already in progress; deferring.\");\n// or defer instead of throwing:\n// Dispatcher.BeginInvoke(() => element.SetResourceReference(...));","typeGuard":"bool IsSafeForThemeStyleUpdate(FrameworkElement e) => !e.IsThemeStyleUpdateInProgress;","tryCatchPattern":"try\n{\n    element.SetResourceReference(StyleProperty, key);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(nameof(SR.CyclicThemeStyleReferenceDetected)) || ex.Message.Contains(\"cyclic\"))\n{\n    Log.Warn(\"Cyclic theme style reference detected; skipped.\", ex);\n}","preventionTips":["Never set Style/theme style properties inside OnInitialized or OnResourcesChanged overrides.","Keep DefaultStyleKey and theme style resource keys constant per control type.","Audit theme styles and BasedOn chains for DynamicResource references that resolve back to the element."],"tags":["wpf","cyclic-reference","theme-style","invalid-operation"],"backgroundTag":"cyclic-style-reference-detected","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"}