dotnet/wpf · error · InvalidEnumArgumentException

InvalidEnumArgumentException("defaultUpdateSourceTrigger"…

Error message

InvalidEnumArgumentException("defaultUpdateSourceTrigger", (int) defaultUpdateSourceTrigger, typeof(UpdateSourceTrigger))

What it means

The FrameworkPropertyMetadata constructor accepting an UpdateSourceTrigger validates the argument: if the value is not one of the defined UpdateSourceTrigger members (per BindingOperations.IsValidUpdateSourceTrigger), an InvalidEnumArgumentException is thrown. This prevents invalid casted integers from masquerading as enum values and poisoning metadata.

Solutions

  1. Pass a defined enum member: UpdateSourceTrigger.PropertyChanged, LostFocus, or Explicit — but note UpdateSourceTrigger.Default is also rejected here (use a concrete trigger).
  2. Validate with BindingOperations.IsValidUpdateSourceTrigger(value) before calling the constructor.
  3. If the value comes from external data, parse it safely with Enum.TryParse<UpdateSourceTrigger> and fall back to a valid default.

Example fix

// before
var trigger = (UpdateSourceTrigger)42;
var meta = new FrameworkPropertyMetadata(null, ..., trigger);
// after
if (BindingOperations.IsValidUpdateSourceTrigger(rawValue)) {
    var meta = new FrameworkPropertyMetadata(null, ..., rawValue); // e.g. UpdateSourceTrigger.PropertyChanged
}
Defensive patterns

Strategy: validation

Validate before calling

UpdateSourceTrigger t;
bool ok = Enum.TryParse(rawValue.ToString(), out t) && BindingOperations.IsValidUpdateSourceTrigger(t) && t != UpdateSourceTrigger.Default;

Type guard

bool IsValidTrigger(object v) => v is UpdateSourceTrigger u && BindingOperations.IsValidUpdateSourceTrigger(u) && u != UpdateSourceTrigger.Default;

Try / catch

try { var meta = new FrameworkPropertyMetadata(null, null, null, false, trigger); } catch (InvalidEnumArgumentException) { trigger = UpdateSourceTrigger.PropertyChanged; }

Prevention

When it happens

Trigger: Calling the FrameworkPropertyMetadata constructor with a defaultUpdateSourceTrigger value outside the UpdateSourceTrigger enum — typically an invalid int cast to UpdateSourceTrigger, or an undefined enum member — when registering a dependency property.

Common situations: Storing the trigger as an int/byte in config or data-binding layers and casting without validating; deserializing an enum value from XML/JSON that contains an out-of-range number; SDK version differences where enum members changed.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkPropertyMetadata.cs:222

        ///     Framework type metadata construction.  Marked as no inline to reduce code size.
        /// </summary>
        /// <param name="defaultValue">Default value of property</param>
        /// <param name="flags">Metadata option flags</param>
        /// <param name="propertyChangedCallback">Called when the property has been changed</param>
        /// <param name="coerceValueCallback">Called on update of value</param>
        /// <param name="isAnimationProhibited">Should animation of this property be prohibited?</param>
        /// <param name="defaultUpdateSourceTrigger">The UpdateSourceTrigger to use for bindings that have UpdateSourceTriger=Default.</param>
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
        public FrameworkPropertyMetadata(object defaultValue,
                                         FrameworkPropertyMetadataOptions flags,
                                         PropertyChangedCallback propertyChangedCallback,
                                         CoerceValueCallback coerceValueCallback,
                                         bool isAnimationProhibited,
                                         UpdateSourceTrigger defaultUpdateSourceTrigger) :
            base(defaultValue, propertyChangedCallback, coerceValueCallback, isAnimationProhibited)
        {
            if (!BindingOperations.IsValidUpdateSourceTrigger(defaultUpdateSourceTrigger))
                throw new InvalidEnumArgumentException("defaultUpdateSourceTrigger", (int) defaultUpdateSourceTrigger, typeof(UpdateSourceTrigger));
            if (defaultUpdateSourceTrigger == UpdateSourceTrigger.Default)
                throw new ArgumentException(SR.NoDefaultUpdateSourceTrigger, nameof(defaultUpdateSourceTrigger));

            TranslateFlags(flags);
            DefaultUpdateSourceTrigger = defaultUpdateSourceTrigger;
        }

        private void Initialize()
        {
            // FW_DefaultUpdateSourceTriggerEnumBit1        = 0x40000000,
            // FW_DefaultUpdateSourceTriggerEnumBit2        = 0x80000000,
            _flags = (MetadataFlags)(((uint)_flags & 0x3FFFFFFF) | ((uint) UpdateSourceTrigger.PropertyChanged) << 30);
        }
        
        private static bool IsFlagSet(FrameworkPropertyMetadataOptions flag, FrameworkPropertyMetadataOptions flags)
        {
            return (flags & flag) != 0;
        }

View on GitHub (pinned to 81131a70a4)