dotnet/wpf · error · InvalidOperationException

SR.BindingExpressionIsDetached

Error message

SR.BindingExpressionIsDetached

What it means

MultiBindingExpression.UpdateSource throws InvalidOperationException when the expression's inner BindingExpressions collection is empty, which indicates the expression is detached (or was never properly created). There is nothing to push values to, so the source update is rejected. The code comments note detached vs. never-populated states are not yet distinguished.

Solutions

  1. Re-acquire the expression via BindingOperations.GetBindingExpression just before calling UpdateSource
  2. Check status/expression validity (e.g. MutableBindingExpressions.Count > 0) before updating
  3. Wrap UpdateSource in try-catch for InvalidOperationException if detachment timing is uncontrollable

Example fix

// before
multiExpr.UpdateSource(); // may be detached
// after
var expr = BindingOperations.GetMultiBindingExpression(target, prop);
if (expr != null && expr.Status != BindingStatusDetached) expr.UpdateSource();
Defensive patterns

Strategy: type-guard

Validate before calling

var expr = BindingOperations.GetMultiBindingExpression(target, prop);
bool canUpdate = expr != null && expr.Status != System.Windows.Data.BindingStatus.Detached;

Type guard

bool IsUsable(MultiBindingExpression e) => e != null && e.Status != BindingStatus.Detached;

Try / catch

try { expr.UpdateSource(); } catch (InvalidOperationException) { /* expression detached; re-acquire and retry once */ }

Prevention

When it happens

Trigger: Calling UpdateSource() on a MultiBindingExpression obtained after the target's binding was removed/replaced (Detach), or on an expression from a DisconnectedItem/ recycled container; holding a reference to an expression across a re-binding.

Common situations: Virtualized ItemsControls recycling containers and later code calling UpdateSource on a stale expression; MVVM code caching BindingExpression and invoking UpdateSource after the control re-binds; calling UpdateSource before the binding ever attached.

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/3271579b18dd0218. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/MultiBindingExpression.cs:111

    }

    //------------------------------------------------------
    //
    //  Public Methods
    //
    //------------------------------------------------------

    /// <summary> Send the current value back to the source(s) </summary>
    /// <remarks> Does nothing when binding's Mode is not TwoWay or OneWayToSource </remarks>
    public override void UpdateSource()
    {
        // ultimately, what would be better would be to have a status flag that
        // indicates that this MultiBindingExpression has been Detached, as opposed to a
        // MultiBindingExpression that doesn't have anything in its BindingExpressions collection
        // in the first place.  Added to which, there should be distinct error
        // messages for both of these error conditions.
        if (MutableBindingExpressions.Count == 0)
            throw new InvalidOperationException(SR.BindingExpressionIsDetached);

        NeedsUpdate = true;     // force update
        Update();               // update synchronously
    }

    /// <summary> Force a data transfer from sources to target </summary>
    /// <remarks> Will transfer data even if binding's Mode is OneWay </remarks>
    public override void UpdateTarget()
    {
        // ultimately, what would be better would be to have a status flag that
        // indicates that this MultiBindingExpression has been Detached, as opposed to a
        // MultiBindingExpression that doesn't have anything in its BindingExpressions collection
        // in the first place.  Added to which, there should be distinct error
        // messages for both of these error conditions.
        if (MutableBindingExpressions.Count == 0)
            throw new InvalidOperationException(SR.BindingExpressionIsDetached);

        UpdateTarget(true);

View on GitHub (pinned to 81131a70a4)