dotnet/wpf · error · InvalidOperationException

SR.InvalidPropertyValue

Error message

SR.InvalidPropertyValue

What it means

DependencyObject.GetEffectiveValue inflates a DeferredReference (a value kept on the WPF property system's deferred store, e.g. from a deferred resource or expression) into a real object. If the inflated value fails DependencyProperty.IsValidValue validation for that property, it throws InvalidOperationException(SR.InvalidPropertyValue, value, dp.Name) — the deferred value has the wrong type/value for the target property.

Solutions

  1. Fix the deferred value's source (resource/style/expression) so it produces the exact type the dependency property expects.
  2. Check IsValidValue before reading: DependencyProperty.IsValidType / property metadata ValidateValueCallback on the candidate object.
  3. Validate XAML resources at design/build time (e.g. enable resource type checks, run XAML compilation) to catch mismatched resource types.

Example fix

<!-- before -->
<Setter Property="FontSize" Value="Red" />
<!-- after -->
<Setter Property="FontSize" Value="12" />
Defensive patterns

Strategy: validation

Validate before calling

object v = deferredValue;
if (dp != null && !dp.IsValidType(v?.GetType() ?? typeof(object)))
    throw new InvalidOperationException($"Value {v} of type {v?.GetType()} is invalid for property {dp.Name}");

Type guard

bool IsValidForProperty(DependencyProperty dp, object value) =>
    value == DependencyProperty.UnsetValue || dp.IsValidType(value.GetType());

Try / catch

try { var value = target.GetValue(MyProperty); }
catch (InvalidOperationException ex) when (ex.Message.Contains("InvalidPropertyValue") || ex.Message.Contains(MyProperty.Name))
{
    target.SetValue(MyProperty, fallbackValue); // recover with a known-good value
}

Prevention

When it happens

Trigger: Reading (GetValue) a dependency property whose stored value came from a deferred provider (style/resource dictionary deferred reference, deferred brush/image) and the deferred object doesn't match the property's type or validation, e.g. a string stored where a Double property expects a number with incompatible type conversion.

Common situations: Resource dictionaries with mistyped resources (a Color where a Brush is expected); cross-version assembly mismatch changing a property's type; theme/style values set through deferred content failing validation at first read.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyObject.cs:326

            if (!entry.HasModifiers)
            {
                // For thread-safety, sealed DOs can't modify _effectiveValues.
                Debug.Assert(!DO_Sealed, "A Sealed DO cannot be modified");

                if (!entry.HasExpressionMarker)
                {
                    // The value for this property was meant to come from a dictionary
                    // and the creation of that value had been deferred until this
                    // time for better performance. Now is the time to actually instantiate
                    // this value by querying it from the dictionary. Once we have the
                    // value we can actually replace the deferred reference marker
                    // with the actual value.
                    DeferredReference reference = (DeferredReference)entry.Value;
                    object value = reference.GetValue(entry.BaseValueSourceInternal);

                    if (!dp.IsValidValue(value))
                    {
                        throw new InvalidOperationException(SR.Format(SR.InvalidPropertyValue, value, dp.Name));
                    }

                    // Make sure the entryIndex is in sync after
                    // the inflation of the deferred reference.
                    entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex);

                    entry.Value = value;

                    _effectiveValues[entryIndex.Index] = entry;
                    return entry;
                }
            }
            else
            {
                // The value for this property was meant to come from a dictionary
                // and the creation of that value had been deferred until this
                // time for better performance. Now is the time to actually instantiate
                // this value by querying it from the dictionary. Once we have the

View on GitHub (pinned to 81131a70a4)