dotnet/wpf · error · InvalidOperationException

SR.BindingExpressionIsDetached

Error message

SR.BindingExpressionIsDetached

What it means

BindingExpression.UpdateSource throws this InvalidOperationException when the binding expression is detached (IsDetached), i.e. no longer connected to its target/source — usually because the target element was unloaded, the binding was replaced, or the target was removed from the visual tree. A detached expression cannot push values back to the source.

Solutions

  1. Verify IsDetached before calling UpdateSource and skip or re-obtain the expression
  2. Re-acquire the expression with target.GetBindingExpression(dp) just before use, instead of caching it
  3. Move the update logic to before detachment (e.g. Updating/commit on Closing of the source element rather than Unloaded)

Example fix

// before
expr.UpdateSource(); // throws if detached
// after
if (!expr.IsDetached) expr.UpdateSource();
Defensive patterns

Strategy: type-guard

Validate before calling

if (expr.IsDetached) return; // skip or re-acquire expression

Type guard

static bool CanUpdate(BindingExpression e) => e != null && !e.IsDetached;

Try / catch

try { expr.UpdateSource(); } catch (InvalidOperationException ex) when (ex.Message.Contains("detached")) { expr = target.GetBindingExpression(targetProperty); if (expr?.IsDetached == false) expr.UpdateSource(); }

Prevention

When it happens

Trigger: Calling BindingExpression.UpdateSource() explicitly on an expression obtained from GetBindingExpression after the target was detached (element unloaded from visual tree, binding replaced, window closed, or ItemsContainer recycled).

Common situations: Saving data on window close by calling UpdateSource on cached BindingExpression references; calling UpdateSource in an Unloaded handler; holding expressions for items removed from an ItemsControl.

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/78168a0fbd010121. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingExpression.cs:183

                // otherwise use the explicit source
                ObjectRef or = ParentBinding.SourceReference;
                return or.GetObject(target, new ObjectRefArgs());
            }
        }

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

        /// <summary> Send the current value back to the source </summary>
        /// <remarks> Does nothing when binding's Mode is not TwoWay or OneWayToSource </remarks>
        public override void UpdateSource()
        {
            if (IsDetached)
                throw new InvalidOperationException(SR.BindingExpressionIsDetached);

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

        /// <summary> Force a data transfer from source to target </summary>
        public override void UpdateTarget()
        {
            if (IsDetached)
                throw new InvalidOperationException(SR.BindingExpressionIsDetached);

            Worker?.RefreshValue();  // calls TransferValue
        }

#region Expression overrides

        /// <summary>
        ///     Notification that a Dependent that this Expression established has

View on GitHub (pinned to 81131a70a4)