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
- Re-acquire the expression via BindingOperations.GetBindingExpression just before calling UpdateSource
- Check status/expression validity (e.g. MutableBindingExpressions.Count > 0) before updating
- 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
- Never cache BindingExpression across re-binds; re-query before use
- Re-fetch expressions after container recycling in virtualized lists
- Check binding Status before calling update APIs
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
- CurrentFixedPageWriter uninitialized
- FixedPageReader
- InvalidEnumArgumentException("value", (int) value…
- InvalidEnumArgumentException("value", (int) value…
- SR.AnnotationServiceNotEnabled
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)