{"record":{"id":"c18aa29db89f68a9","repo":"dotnet/wpf","slug":"sr-resourcedictionaryinvalidmergeddictionary","errorCode":null,"errorMessage":"SR.ResourceDictionaryInvalidMergedDictionary","messagePattern":"SR\\.ResourceDictionaryInvalidMergedDictionary","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs","lineNumber":1506,"sourceCode":"\n                    // do not call AddInheritanceContextToValues -\n                    // the owner is an Application, and we'll be\n                    // calling SealValues soon, which takes care\n                    // of InheritanceContext as well\n                }\n\n            }\n\n            FrameworkElement fe = owner as FrameworkElement;\n            if (fe != null)\n            {\n                if (_ownerFEs == null)\n                {\n                    _ownerFEs = new WeakReferenceList(1);\n                }\n                else if (_ownerFEs.Contains(fe) && ContainsCycle(this))\n                {\n                    throw new InvalidOperationException(SR.ResourceDictionaryInvalidMergedDictionary);\n                }\n\n                // Propagate the HasImplicitStyles flag to the new owner\n                if (HasImplicitStyles)\n                {\n                    fe.ShouldLookupImplicitStyles = true;\n                }\n\n                _ownerFEs.Add(fe);\n            }\n            else\n            {\n                FrameworkContentElement fce = owner as FrameworkContentElement;\n                if (fce != null)\n                {\n                    if (_ownerFCEs == null)\n                    {\n                        _ownerFCEs = new WeakReferenceList(1);","sourceCodeStart":1488,"sourceCodeEnd":1524,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs#L1488-L1524","documentation":"Thrown as InvalidOperationException from OnHierarchyInvalidated/owner registration (AddOwner path for FrameworkElement) when a merged ResourceDictionary would create a cycle — the element already owns this dictionary and the dictionary graph contains a cycle back to itself. WPF forbids circular merged-dictionary chains.","triggerScenarios":"Calling AddOwner (or MergedDictionaries.Add producing an ownership link) where the same FrameworkElement is already an owner of the dictionary and ContainsCycle(this) detects a loop, e.g. dictionary A merges B and B merges A.","commonSituations":"Two resource dictionaries merged into each other; a UserControl's resources merging a dictionary that (transitively) merges the control's own resources; theme/generic.xaml chains that loop after refactoring.","solutions":["Break the cycle: remove the MergedDictionaries entry that points back to an ancestor dictionary","Extract shared resources into a third dictionary that both merge, instead of cross-merging","Draw the merged-dictionary graph and ensure it is a DAG","Replace runtime self-merge code with a single well-known source dictionary"],"exampleFix":"// before\n// DictA.MergedDictionaries contains DictB and DictB.MergedDictionaries contains DictA\n// after\nvar shared = new ResourceDictionary { Source = new Uri(\"shared.xaml\", UriKind.Relative) };\ndictA.MergedDictionaries.Add(shared);\ndictB.MergedDictionaries.Add(shared); // no cycle","handlingStrategy":"validation","validationCode":"bool wouldCycle = dict.MergedDictionaries.Contains(target) || ContainsCycleTransitively(dict, target);","typeGuard":null,"tryCatchPattern":"try { dict.AddOwner(fe); } catch (InvalidOperationException) { /* remove offending MergedDictionaries entry */ }","preventionTips":["Keep the merged-dictionary graph acyclic by design","Never merge a dictionary that (transitively) merges its own owner","Extract shared resources into leaf dictionaries"],"tags":["wpf","resourcedictionary","merged-dictionaries","cycle"],"backgroundTag":"invalid-state-transition","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"}