{"record":{"id":"273cad6a5fe645de","repo":"dotnet/wpf","slug":"sr-propertynotreadonly","errorCode":null,"errorMessage":"SR.PropertyNotReadOnly","messagePattern":"SR\\.PropertyNotReadOnly","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyProperty.cs","lineNumber":538,"sourceCode":"            SetupOverrideMetadata(forType, typeMetadata, out dType, out baseMetadata);\n\n            ArgumentNullException.ThrowIfNull(key);\n\n            if (ReadOnly)\n            {\n                // If the property is read-only, the key must match this property\n                //  and the key must match that in the base metadata.\n\n                if (key.DependencyProperty != this)\n                {\n                    throw new ArgumentException(SR.Format(SR.ReadOnlyOverrideKeyNotAuthorized, Name));\n                }\n\n                VerifyReadOnlyKey(key);\n            }\n            else\n            {\n                throw new InvalidOperationException(SR.PropertyNotReadOnly);\n            }\n\n            // Either the property doesn't require a key, or the key match was\n            //  successful.  Proceed with the metadata override.\n            ProcessOverrideMetadata(forType, typeMetadata, dType, baseMetadata);\n        }\n\n        /// <summary>\n        ///     After parameters have been validated for OverrideMetadata, this\n        /// method is called to actually update the data structures.\n        /// </summary>\n        private void ProcessOverrideMetadata(\n            Type forType,\n            PropertyMetadata typeMetadata,\n            DependencyObjectType dType,\n            PropertyMetadata baseMetadata)\n        {\n            // Store per-Type metadata for this property. Locks only on Write.","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyProperty.cs#L520-L556","documentation":"OverrideMetadata throws this InvalidOperationException when a key is passed (the three-argument overload) but the property is NOT read-only. Keys exist exclusively to authorize operations on read-only properties, so supplying a DependencyPropertyKey for a writable property is a programming error.","triggerScenarios":"Calling writableDp.OverrideMetadata(forType, typeMetadata, someKey) where writableDp was registered with DependencyProperty.Register (not RegisterReadOnly).","commonSituations":"Copy-pasting an override call from a read-only DP to a writable one and leaving the key argument in place; a helper method that always forwards a key.","solutions":["Use the two-argument overload: writableDp.OverrideMetadata(forType, typeMetadata)","Remove the DependencyPropertyKey argument from the call","Keep separate helper methods for read-only vs writable metadata overrides so keys are only threaded through read-only paths"],"exampleFix":"// before\nMyWritableProperty.OverrideMetadata(typeof(MyControl), meta, SomeReadOnlyKey); // throws\n// after\nMyWritableProperty.OverrideMetadata(typeof(MyControl), meta); // writable DP takes no key","handlingStrategy":"validation","validationCode":"if (!dp.ReadOnly && key != null)\n    throw new InvalidOperationException(\"Writable DP: use the two-argument OverrideMetadata\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only thread DependencyPropertyKey through read-only code paths","Use the two-argument OverrideMetadata overload for writable DPs","Review copy-pasted override calls for leftover key arguments"],"tags":["wpf","dependency-property","read-only","invalid-operation","argument-mismatch"],"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"}