{"record":{"id":"adf5c0ed2e422486","repo":"dotnet/wpf","slug":"sr-resourcedictionaryisreadonly","errorCode":null,"errorMessage":"SR.ResourceDictionaryIsReadOnly","messagePattern":"SR\\.ResourceDictionaryIsReadOnly","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs","lineNumber":435,"sourceCode":"        // property in this scenario.\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        public DeferrableContent DeferrableContent\n        {\n            get\n            {\n                return null;\n            }\n            set\n            {\n                this.SetDeferrableContent(value);\n            }\n        }\n\n        private void SetValueWithoutLock(object key, object value)\n        {\n            if (IsReadOnly)\n            {\n                throw new InvalidOperationException(SR.ResourceDictionaryIsReadOnly);\n            }\n\n            object oldValue = _baseDictionary[key];\n\n            if (oldValue != value)\n            {\n                // We need to validate all the deferred references that refer\n                // to the old resource before we overwrite it.\n                ValidateDeferredResourceReferences(key);\n\n                if( TraceResourceDictionary.IsEnabled )\n                {\n                    TraceResourceDictionary.Trace( TraceEventType.Start,\n                                                   TraceResourceDictionary.AddResource,\n                                                   this,\n                                                   key,\n                                                   value );\n                }","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs#L417-L453","documentation":"SetValueWithoutLock throws InvalidOperationException when the dictionary is read-only (IsReadOnly). A dictionary becomes read-only while it is being enumerated inside a deferred-content load or when it is marked immutable (e.g. during a DeferContent load or when sealed by the system), so writes via the indexer are rejected.","triggerScenarios":"Setting dictionary[key] = value (this[key]) or other write paths while IsReadOnly is true — typically while another thread is enumerating/loading the dictionary's deferred content, or after the dictionary was sealed/invalidated.","commonSituations":"Theming code writing into a shared Application-level Resources dictionary while a load/enumeration is in flight; modifying dictionaries on frozen/sealed theme resources.","solutions":["Wait until deferred content load completes (e.g. after a Dispatcher pass) before writing to the dictionary.","Use BeginInit/EndInit around bulk modifications instead of writing during load.","Clone or create a new ResourceDictionary with the desired values and replace the read-only one in MergedDictionaries."],"exampleFix":"// before\napp.Resources[\"Accent\"] = Brushes.Blue; // may hit read-only during load\n// after\nvar rd = new ResourceDictionary { [\"Accent\"] = Brushes.Blue };\napp.Resources.MergedDictionaries.Add(rd);","handlingStrategy":"validation","validationCode":"if (dictionary.IsReadOnly) throw new InvalidOperationException(\"Cannot write to a read-only ResourceDictionary; wait for load/enumeration to finish or replace the dictionary\");","typeGuard":"bool CanWrite(ResourceDictionary rd) => !rd.IsReadOnly;","tryCatchPattern":"try { dictionary[key] = value; } catch (InvalidOperationException ex) when (ex.Message.Contains(\"read-only\")) { Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => dictionary[key] = value)); }","preventionTips":["Check IsReadOnly before mutating a shared ResourceDictionary","Perform all dictionary mutations on the UI thread outside load/enumeration windows","Prefer replacing a whole merged dictionary over in-place writes on shared dictionaries"],"tags":["wpf","resourcedictionary","readonly"],"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"}