AvaloniaUI/Avalonia · error · InvalidOperationException

Cannot add value to DoNothing binding value.

Error message

Cannot add value to DoNothing binding value.

What it means

Thrown as InvalidOperationException by BindingValue<T>.WithValue(T) when the current Type is BindingValueType.DoNothing. A DoNothing binding value signals the pipeline to take no action; attaching a value to it is semantically invalid. UnsetValue is allowed (it transitions to Value), but DoNothing is terminal.

Source

Thrown at src/Avalonia.Base/Data/BindingValue.cs:183

                    new BindingNotification(Error!, BindingErrorType.DataValidationError, Value),
                _ => throw new NotSupportedException("Invalid BindingValueType."),
            };
        }

        /// <summary>
        /// Returns a new binding value with the specified value.
        /// </summary>
        /// <param name="value">The new value.</param>
        /// <returns>The new binding value.</returns>
        /// <exception cref="InvalidOperationException">
        /// The binding type is <see cref="BindingValueType.UnsetValue"/> or
        /// <see cref="BindingValueType.DoNothing"/>.
        /// </exception>
        public BindingValue<T> WithValue(T value)
        {
            if (Type == BindingValueType.DoNothing)
            {
                throw new InvalidOperationException("Cannot add value to DoNothing binding value.");
            }

            var type = Type == BindingValueType.UnsetValue ? BindingValueType.Value : Type;
            return new BindingValue<T>(type | BindingValueType.HasValue, value, Error);
        }

        /// <summary>
        /// Gets the value of the binding value if present, otherwise the default value.
        /// </summary>
        /// <returns>The value.</returns>
        public T? GetValueOrDefault() => HasValue ? _value : default;

        /// <summary>
        /// Gets the value of the binding value if present, otherwise a default value.
        /// </summary>
        /// <param name="defaultValue">The default value.</param>
        /// <returns>The value.</returns>
        public T? GetValueOrDefault(T defaultValue) => HasValue ? _value : defaultValue;

View on GitHub (pinned to 11c5427268)

Solutions

  1. Check that Type is not DoNothing before calling WithValue; for DoNothing, propagate it unchanged.
  2. If you need a fallback on error, construct a BindingErrorWithFallback via the factory instead of calling WithValue on a DoNothing.
  3. Branch on Type: only call WithValue when Type is UnsetValue or Value.

Example fix

// before
var result = donothingValue.WithValue(fallback); // throws
// after
var result = donothingValue.Type == BindingValueType.DoNothing
    ? donothingValue
    : donothingValue.WithValue(fallback);
Defensive patterns

Strategy: validation

Validate before calling

if (bindingValue.Type != BindingValueType.DoNothing)
    bindingValue = bindingValue.WithValue(value);

Type guard

static bool CanAcceptValue<T>(BindingValue<T> bv) => bv.Type != BindingValueType.DoNothing;

Try / catch

try { bindingValue = bindingValue.WithValue(value); }
catch (InvalidOperationException ex) when (ex.Message.Contains("DoNothing"))
{ /* propagate the DoNothing value unchanged */ }

Prevention

When it happens

Trigger: Calling bindingValue.WithValue(x) on a BindingValue whose Type == BindingValueType.DoNothing. WithValue first checks for DoNothing and throws before any other logic.

Common situations: Chaining WithValue on a binding value produced by a 'do nothing' sentinel without checking Type first. Composing binding results where one branch intentionally returns DoNothing and a later step tries to attach a fallback value.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/7bcd7783974d2410. Report an issue: GitHub.