{"record":{"id":"3271579b18dd0218","repo":"dotnet/wpf","slug":"sr-bindingexpressionisdetached-multibindingexpression","errorCode":null,"errorMessage":"SR.BindingExpressionIsDetached","messagePattern":"SR\\.BindingExpressionIsDetached","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/MultiBindingExpression.cs","lineNumber":111,"sourceCode":"    }\n\n    //------------------------------------------------------\n    //\n    //  Public Methods\n    //\n    //------------------------------------------------------\n\n    /// <summary> Send the current value back to the source(s) </summary>\n    /// <remarks> Does nothing when binding's Mode is not TwoWay or OneWayToSource </remarks>\n    public override void UpdateSource()\n    {\n        // ultimately, what would be better would be to have a status flag that\n        // indicates that this MultiBindingExpression has been Detached, as opposed to a\n        // MultiBindingExpression that doesn't have anything in its BindingExpressions collection\n        // in the first place.  Added to which, there should be distinct error\n        // messages for both of these error conditions.\n        if (MutableBindingExpressions.Count == 0)\n            throw new InvalidOperationException(SR.BindingExpressionIsDetached);\n\n        NeedsUpdate = true;     // force update\n        Update();               // update synchronously\n    }\n\n    /// <summary> Force a data transfer from sources to target </summary>\n    /// <remarks> Will transfer data even if binding's Mode is OneWay </remarks>\n    public override void UpdateTarget()\n    {\n        // ultimately, what would be better would be to have a status flag that\n        // indicates that this MultiBindingExpression has been Detached, as opposed to a\n        // MultiBindingExpression that doesn't have anything in its BindingExpressions collection\n        // in the first place.  Added to which, there should be distinct error\n        // messages for both of these error conditions.\n        if (MutableBindingExpressions.Count == 0)\n            throw new InvalidOperationException(SR.BindingExpressionIsDetached);\n\n        UpdateTarget(true);","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/MultiBindingExpression.cs#L93-L129","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nmultiExpr.UpdateSource(); // may be detached\n// after\nvar expr = BindingOperations.GetMultiBindingExpression(target, prop);\nif (expr != null && expr.Status != BindingStatusDetached) expr.UpdateSource();","handlingStrategy":"type-guard","validationCode":"var expr = BindingOperations.GetMultiBindingExpression(target, prop);\nbool canUpdate = expr != null && expr.Status != System.Windows.Data.BindingStatus.Detached;","typeGuard":"bool IsUsable(MultiBindingExpression e) => e != null && e.Status != BindingStatus.Detached;","tryCatchPattern":"try { expr.UpdateSource(); } catch (InvalidOperationException) { /* expression detached; re-acquire and retry once */ }","preventionTips":["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"],"tags":["wpf","binding","detached","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}