dotnet/wpf · error · ArgumentException

SR.DefaultValueMayNotBeExpression

Error message

SR.DefaultValueMayNotBeExpression

What it means

An Expression instance cannot be used as a dependency property default value because defaults are copied/stored raw and never evaluated, producing incorrect behavior. WPF explicitly rejects Expression defaults during metadata validation.

Solutions

  1. Use a plain value (or null) as the default.
  2. Apply bindings/animations after element construction (e.g. in XAML or via SetBinding) rather than as a default.
  3. If deferred value computation is needed, use a value converter or CoerceValueCallback instead.

Example fix

// before
new PropertyMetadata(new Binding("ViewModelValue"))
// after
new PropertyMetadata(null) // bind in XAML or via SetBinding at runtime
Defensive patterns

Strategy: validation

Validate before calling

if (defaultValue is System.Windows.Expression) throw new ArgumentException("Default may not be an Expression");

Type guard

static bool IsNotExpression(object v) => v is not System.Windows.Expression;

Prevention

When it happens

Trigger: new PropertyMetadata(BindingOperations.SomeExpression) or passing any Expression-derived object as the defaultValue of Register/OverrideMetadata/AddOwner metadata.

Common situations: Developers trying to make a property's default a Binding or dynamic expression instead of setting the binding in XAML/code after construction.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

        private static void ValidateDefaultValueCommon(
            object defaultValue,
            Type propertyType,
            string propertyName,
            ValidateValueCallback validateValueCallback,
            bool checkThreadAffinity)
        {
            // Ensure default value is the correct type
            if (!IsValidType(defaultValue, propertyType))
            {
                throw new ArgumentException(SR.Format(SR.DefaultValuePropertyTypeMismatch, propertyName));
            }

            // An Expression used as default value won't behave as expected since
            //  it doesn't get evaluated.  We explicitly fail it here.
            if (defaultValue is Expression )
            {
                throw new ArgumentException(SR.DefaultValueMayNotBeExpression);
            }

            if (checkThreadAffinity)
            {
                // If the default value is a DispatcherObject with thread affinity
                // we cannot accept it as a default value. If it implements ISealable
                // we attempt to seal it; if not we throw  an exception. Types not
                // deriving from DispatcherObject are allowed - it is up to the user to
                // make any custom types free-threaded.


                if (defaultValue is DispatcherObject dispatcherObject && dispatcherObject.Dispatcher != null)
                {
                    // Try to make the DispatcherObject free-threaded if it's an
                    // ISealable.


                    if (dispatcherObject is ISealable valueAsISealable && valueAsISealable.CanSeal)

View on GitHub (pinned to 81131a70a4)