dotnet/wpf · error · InvalidOperationException
SR.Format(SR.BindingExpressionStatusChanged, _status…
Error message
SR.Format(SR.BindingExpressionStatusChanged, _status, status)
What it means
SetStatus is the single mutation point for a binding expression's internal status. Once an expression is Detached (removed from its binding target), its status is frozen; attempting to transition to any different status throws this InvalidOperationException, preventing post-detach state corruption. The message includes the current status and the requested one.
Solutions
- Do not reuse BindingExpression objects after detach; create a new Binding and call SetBinding again.
- Ensure UpdateSource/UpdateTarget calls only happen while the binding is attached (check expression.IsDetached first).
- If holding references to BindingExpressionBase, null them out on Unloaded/Detached events instead of reusing them.
Example fix
// before var expr = (BindingExpression)textBox.GetBindingExpression(TextBox.TextProperty); // ... element detached ... expr.UpdateSource(); // throws // after var expr = (BindingExpression)textBox.GetBindingExpression(TextBox.TextProperty); if (expr != null && !expr.IsDetached) expr.UpdateSource();
Defensive patterns
Strategy: type-guard
Type guard
bool CanUpdate(BindingExpressionBase expr) => expr != null && !expr.IsDetached;
Try / catch
try { expr.UpdateSource(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("status"))
{
// expression detached; recreate binding
} Prevention
- Check IsDetached before reusing a BindingExpression
- Drop cached expression references on Unloaded
- Create fresh bindings rather than reactivating detached ones
When it happens
Trigger: Calling SetStatus with a status different from the current one on an expression whose IsDetached is true — typically from reactivating, transferring, or updating a BindingExpressionBase after Detach (e.g. reusing a BindingExpression whose target property or element was cleared).
Common situations: Reusing binding expression objects across element re-templating; updating a binding after the element was removed from the visual tree; custom code or third-party frameworks that poke at binding internals during unload.
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.BindingGroup_CannotChangeGroups
- SR.Format(SR.CannotCallRunMultipleTimes…
- SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Sorting")
- SR.Format(SR.MemberNotAllowedForView, "AddNew")
- SR.Panel_BoundPanel_NoChildren
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f115f8ad1925c4b3.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingExpressionBase.cs:2106
{
// set IEnumerable properties (e.g. ItemsSource) to null, so that
// the control can disconnect from the individual items
newValue = null;
}
// notify the target property about the new value (cheaply)
if (newValue != DependencyProperty.UnsetValue)
{
ChangeValue(newValue, false);
Invalidate(false);
}
}
internal void SetStatus(BindingStatusInternal status)
{
if (IsDetached && status != _status)
{
throw new InvalidOperationException(SR.Format(SR.BindingExpressionStatusChanged, _status, status));
}
_status = status;
}
// convert a user-supplied fallback value to a usable equivalent
// returns: UnsetValue if user did not supply a fallback value
// value if fallback value is legal
// DefaultValueObject otherwise
internal static object ConvertFallbackValue(object value, DependencyProperty dp, object sender)
{
Exception e;
object result = ConvertValue(value, dp, out e);
if (result == DefaultValueObject)
{
if (TraceData.IsEnabled)
{View on GitHub (pinned to 81131a70a4)