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
- Verify IsDetached before calling UpdateSource and skip or re-obtain the expression
- Re-acquire the expression with target.GetBindingExpression(dp) just before use, instead of caching it
- 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
- Re-acquire BindingExpression via GetBindingExpression right before use; avoid caching
- Avoid calling UpdateSource from Unloaded handlers or after element removal
- Check IsDetached defensively in save/commit code paths
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
- SR.ChangeSealedBinding
- SR.Format(SR.BindingConflict, SourceProperties.ElementName…
- SR.Format(SR.CannotChangeLiveShaping, "IsLiveFiltering"…
- SR.Format(SR.CannotChangeLiveShaping, "IsLiveSorting"…
- SR.Format(SR.RequiresExplicitCulture, TargetProperty.Name)
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 hasView on GitHub (pinned to 81131a70a4)