dotnet/wpf · error · InvalidOperationException

SR.Format(SR.ReadOnlyOverrideNotAllowed, Name)

Error message

SR.Format(SR.ReadOnlyOverrideNotAllowed, Name)

What it means

DependencyProperty.OverrideMetadata throws this InvalidOperationException when the property being overridden is read-only (ReadOnly is true) and the overload of OverrideMetadata without a DependencyPropertyKey is used. Read-only properties can only have their metadata overridden through the key-protected overload, to prevent arbitrary code from modifying metadata that only the property's definer should control.

Solutions

  1. Use the key-protected overload: store the DependencyPropertyKey used at registration and call key.DependencyProperty.OverrideMetadata(forType, typeMetadata, key)
  2. If you do not own the key (property defined in a type you cannot change), do not override the metadata; instead set the value via the key only from the defining type, or wrap with your own property
  3. If the property should be writable, re-register it as a normal DependencyProperty instead of via DependencyPropertyKey

Example fix

// before
public class MyControl : Control
{
    static MyControl()
    {
        // IsMouseOverProperty is read-only
        IsMouseOverProperty.OverrideMetadata(typeof(MyControl), new PropertyMetadata(false)); // throws
    }
}
// after
public class MyControl : Control
{
    static MyControl()
    {
        // Only valid if you hold the key (owning type):
        // ReadOnlyPropertyKey.OverrideMetadata(typeof(MyControl), new PropertyMetadata(false));
        // or override using the key:
        // MyReadOnlyProperty.OverrideMetadata(typeof(MyControl), meta, MyReadOnlyPropertyKey);
    }
}
Defensive patterns

Strategy: validation

Validate before calling

if (dp.ReadOnly)
    dp.OverrideMetadata(typeof(MyControl), meta, /* must supply the DependencyPropertyKey here */ key);
else
    dp.OverrideMetadata(typeof(MyControl), meta);

Type guard

static bool CanOverrideWithoutKey(DependencyProperty dp) => !dp.ReadOnly;

Prevention

When it happens

Trigger: Calling dp.OverrideMetadata(forType, typeMetadata) (the two-argument public overload) where dp was registered via DependencyPropertyKey.DependencyProperty, i.e. ReadOnly == true.

Common situations: Subclassing a control and trying to override metadata (e.g. default value, FrameworkPropertyMetadataOptions) of a read-only property like UIElement.IsMouseOver or a custom read-only DP; copy-pasting override code from a writable DP to a read-only one.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/db9758cc211b8001. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyProperty.cs:504

        /// <summary>
        ///     Supply metadata for given type & run static constructors if needed.
        /// </summary>
        /// <remarks>
        ///     The supplied metadata will be merged with the type's base
        ///     metadata
        /// </remarks>
        public void OverrideMetadata(Type forType, PropertyMetadata typeMetadata)
        {
            DependencyObjectType dType;
            PropertyMetadata baseMetadata;

            SetupOverrideMetadata(forType, typeMetadata, out dType, out baseMetadata);

            if (ReadOnly)
            {
                // Readonly and no DependencyPropertyKey - not allowed.
                throw new InvalidOperationException(SR.Format(SR.ReadOnlyOverrideNotAllowed, Name));
            }

            ProcessOverrideMetadata(forType, typeMetadata, dType, baseMetadata);
        }

        /// <summary>
        ///     Supply metadata for a given type, overriding a property that is
        /// read-only.  If property is not read only, tells user to use the Plain
        /// Jane OverrideMetadata instead.
        /// </summary>
        public void OverrideMetadata(Type forType, PropertyMetadata typeMetadata, DependencyPropertyKey key)
        {
            DependencyObjectType dType;
            PropertyMetadata baseMetadata;

            SetupOverrideMetadata(forType, typeMetadata, out dType, out baseMetadata);

            ArgumentNullException.ThrowIfNull(key);

View on GitHub (pinned to 81131a70a4)