AvaloniaUI/Avalonia · error · NotSupportedException
LogicalAncestorNode is invalid in conjunction with a binding
Error message
LogicalAncestorNode is invalid in conjunction with a binding source.
What it means
LogicalAncestorElementNode.SelectSource throws NotSupportedException when an explicit binding source is set (source != UnsetValue) together with a $parent logical-ancestor relative source. The logical-ancestor traversal walks the logical tree from the target, so an explicit Source is contradictory and not allowed.
Source
Thrown at src/Avalonia.Base/Data/Core/ExpressionNodes/LogicalAncestorElementNode.cs:45
if (_ancestorType is not null)
{
builder.Append(_ancestorType.Name);
if (_ancestorLevel > 0)
builder.Append(',');
}
if (_ancestorLevel > 0)
builder.Append(_ancestorLevel);
builder.Append(']');
}
}
public override object? SelectSource(object? source, object target, object? anchor)
{
if (source != AvaloniaProperty.UnsetValue)
throw new NotSupportedException(
"LogicalAncestorNode is invalid in conjunction with a binding source.");
if (target is ILogical)
return target;
if (anchor is ILogical)
return anchor;
throw new InvalidOperationException("Cannot find an ILogical to get a logical ancestor.");
}
public override bool ShouldLogErrors(object target)
{
return target is ILogical logical && logical.IsAttachedToLogicalTree;
}
protected override void OnSourceChanged(object? source, Exception? dataValidationError)
{
if (!ValidateNonNullSource(source))
return;
View on GitHub (pinned to 11c5427268)
Solutions
- Remove the explicit Source so the logical-ancestor RelativeSource can traverse from the target.
- If you need a fixed source, drop the logical-ancestor relative source and bind the source object directly.
Example fix
// before
{Binding $parent[ItemsControl].Items, Source={StaticResource x}}
// after
{Binding $parent[ItemsControl].Items} Defensive patterns
Strategy: validation
Validate before calling
// Logical-ancestor RelativeSource and explicit Source are mutually exclusive.
bool UsesLogicalAncestor(Binding b) =>
b.RelativeSource is RelativeSource rs && rs.Mode == RelativeSourceMode.FindAncestor;
if (UsesLogicalAncestor(binding) && binding.Source is not null)
throw new InvalidOperationException("Cannot combine logical-ancestor RelativeSource with Source."); Try / catch
try { target.Bind(prop, binding); }
catch (NotSupportedException ex) when (ex.Message.Contains("LogicalAncestorNode"))
{ /* drop Source or the relative source */ } Prevention
- Use exactly one source strategy per binding.
- In control templates, prefer $parent/$self over mixing with Source.
- Review bindings after refactoring RelativeSource usage.
When it happens
Trigger: Combining Binding.Source with a path that uses a logical-ancestor RelativeSource ($parent[...] or $self-relative), or specifying both a Source and RelativeSource in the same binding.
Common situations: Adding Source= to a control-template binding that already uses $parent; mixing ElementName/Source with RelativeSource in one binding descriptor.
Related errors
- Cannot find an ILogical to get a logical ancestor.
- Cannot find an ILogical to get a visual ancestor.
- DataContextNode is invalid in conjunction with a binding sou
- Cannot find a DataContext to bind to.
- TemplatedParentNode is invalid in conjunction with a binding
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/6bd3b35382af1849.
Report an issue: GitHub.