dotnet/wpf · error · InvalidOperationException

InvalidOperationException()

Error message

InvalidOperationException()

What it means

DependencyPropertyKey.OverrideMetadata throws a bare InvalidOperationException when the key's _dp field is null — the key was never actually bound to a dependency property, i.e. it was not produced (or is no longer backed) by a DependencyPropertyKey registration. Calling OverrideMetadata on such an unbound key cannot proceed.

Solutions

  1. Ensure the key comes from DependencyProperty.RegisterReadOnly (or RegisterAttachedReadOnly) and that the returned key is the one used
  2. Check that the static key field is initialized before OverrideMetadata is called (static-field initialization order in the declaring type)
  3. If _dp can be null in your scenario, guard: only call key.OverrideMetadata after verifying key.DependencyProperty != null

Example fix

// before
private static DependencyPropertyKey MyPropKey; // never assigned
MyPropKey.OverrideMetadata(typeof(C), meta); // _dp == null -> throws
// after
private static readonly DependencyPropertyKey MyPropKey =
    DependencyProperty.RegisterReadOnly(nameof(MyProp), typeof(object), typeof(Owner), new PropertyMetadata());
MyPropKey.OverrideMetadata(typeof(C), meta); // key is bound to a real DP
Defensive patterns

Strategy: type-guard

Validate before calling

if (key == null || key.DependencyProperty == null)
    throw new InvalidOperationException("DependencyPropertyKey is not bound to a DP");

Type guard

static bool IsUsableKey(DependencyPropertyKey key) => key?.DependencyProperty != null;

Try / catch

try { key.OverrideMetadata(forType, meta); }
catch (InvalidOperationException) { /* unbound key: re-create via RegisterReadOnly */ }

Prevention

When it happens

Trigger: Constructing a DependencyPropertyKey via its (non-public) constructor or getting a default-initialized instance and calling OverrideMetadata on it; deserialization or reflection paths that yield a key without _dp set; misuse in unit tests (see the listed test names exercising null/invalid forType and metadata cases).

Common situations: Keys stored in fields that were never assigned the RegisterReadOnly result; serialization round-trips dropping the internal _dp link; test scaffolding creating throwaway keys.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyPropertyKey.cs:44

            {
                return _dp;
            }
        }

        internal DependencyPropertyKey(DependencyProperty dp)
        {
            _dp = dp;
        }

        /// <summary>
        ///     Override the metadata of a property that is already secured with
        /// this key.
        /// </summary>
        public void OverrideMetadata( Type forType, PropertyMetadata typeMetadata )
        {
            if( _dp == null )
            {
                throw new InvalidOperationException();
            }

            _dp.OverrideMetadata( forType, typeMetadata, this );
        }

        // This is not a property setter because we can't have a public
        //  property getter and a internal property setter on the same property.
        internal void SetDependencyProperty(DependencyProperty dp)
        {
            Debug.Assert(_dp==null,"This should only be used when we need a placeholder and have a temporary value of null. It should not be used to change this property.");
            _dp = dp;
        }

        private DependencyProperty _dp = null;
    }
}

View on GitHub (pinned to 81131a70a4)