AvaloniaUI/Avalonia · error · InvalidOperationException
BindingExpression was already attached to a different proper
Error message
BindingExpression was already attached to a different property.
What it means
AttachCore rejects attaching an already-attached expression to a different AvaloniaProperty than the one it was first bound to. A binding expression is tied to one target property; switching properties indicates a logic error or accidental reuse.
Source
Thrown at src/Avalonia.Base/Data/Core/UntypedBindingExpressionBase.cs:269
/// possible.
/// </summary>
/// <param name="value">The value to write.</param>
/// <returns>
/// True if the value could be written to the binding source; otherwise false.
/// </returns>
internal virtual bool WriteValueToSource(object? value) => false;
private void AttachCore(
IBindingExpressionSink sink,
ImmediateValueFrame? frame,
AvaloniaObject target,
AvaloniaProperty? targetProperty,
BindingPriority priority)
{
if (_sink is not null)
throw new InvalidOperationException("BindingExpression was already attached.");
if (TargetProperty is not null && TargetProperty != targetProperty)
throw new InvalidOperationException("BindingExpression was already attached to a different property.");
_sink = sink;
_frame = frame;
_target = new(target);
TargetProperty = targetProperty;
TargetType = targetProperty?.PropertyType ?? typeof(object);
Priority = priority;
}
/// <summary>
/// Converts a value using a value converter, logging a warning if necessary.
/// </summary>
/// <param name="converter">The value converter.</param>
/// <param name="converterCulture">The culture to use for the conversion.</param>
/// <param name="converterParameter">The converter parameter.</param>
/// <param name="value">The value to convert.</param>
/// <param name="targetType">The target type to convert to.</param>View on GitHub (pinned to 11c5427268)
Solutions
- Create a new expression instance per target property via CreateInstance.
- Ensure each control+property pair gets its own expression; never reuse one instance across properties.
- Audit caching layers that hand out the same expression to multiple property bindings.
Example fix
// before: expr.Attach(..., PropertyA, ...); expr.Attach(..., PropertyB, ...); // throws // after: var exprA = binding.CreateInstance(t, PropertyA, anchor); var exprB = binding.CreateInstance(t, PropertyB, anchor);
Defensive patterns
Strategy: validation
Validate before calling
// One expression per (target, property) pair. var exprA = binding.CreateInstance(t, PropertyA, anchor); var exprB = binding.CreateInstance(t, PropertyB, anchor);
Prevention
- Never reuse an expression across different properties.
- Audit shared/cached expressions for cross-property reuse.
- Create fresh instances for each property binding.
When it happens
Trigger: Attaching the same binding expression instance to target property A, then later to target property B (where TargetProperty was already recorded as A).
Common situations: Sharing one expression object across two different properties, or rebinding a detached-looking (but not actually detached) expression to a new property.
Related errors
- BindingExpression was already attached.
- BindingExpression has not been started.
- Cannot call AsObservable on a to binding expression which is
- Cannot subscribe to IndexerDescriptor.
- Cannot create ElementName binding when NameScope is null
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/43bc044f2cc7c01c.
Report an issue: GitHub.