AvaloniaUI/Avalonia · error · ExpressionParseException
Unable to parse '{expression}': expected an instance of '{_h
Error message
Unable to parse '{expression}': expected an instance of '{_head}' but got '{visited}'. What it means
BindingExpressionVisitor maintains a single `_head` representing the current end of the path. The private Add method re-visits the instance of each new node and requires it to equal `_head`; if the visited instance is not the current head (broken chain, method on a different object, static that detaches from the parameter), it throws ExpressionParseException. This is the generic 'the expression is not a continuous path rooted at the lambda parameter' error.
Source
Thrown at src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs:274
}
protected override Expression VisitTry(TryExpression node)
{
throw new ExpressionParseException(0, $"Invalid expression type in binding expression: {node.NodeType}.");
}
protected override Expression VisitTypeBinary(TypeBinaryExpression node)
{
throw new ExpressionParseException(0, $"Invalid expression type in binding expression: {node.NodeType}.");
}
private Expression Add(Expression? instance, Expression expression, Action<CompiledBindingPathBuilder> build)
{
var visited = Visit(instance);
if (visited != _head)
{
throw new ExpressionParseException(
0,
$"Unable to parse '{expression}': expected an instance of '{_head}' but got '{visited}'.");
}
build(_builder);
return _head = expression;
}
private Expression AddPropertyNode(MemberExpression node)
{
// Check if it's an AvaloniaProperty accessed via CLR wrapper
if (typeof(AvaloniaObject).IsAssignableFrom(node.Expression?.Type) &&
AvaloniaPropertyRegistry.Instance.FindRegistered(node.Expression.Type, node.Member.Name) is { } avaloniaProperty)
{
return Add(
node.Expression,
node,
x => x.Property(avaloniaProperty, CreateAvaloniaPropertyAccessor));View on GitHub (pinned to 11c5427268)
Solutions
- Make the binding a single continuous chain rooted at the lambda parameter (x => x.A.B.C).
- Move helper calls into a view-model property or an IValueConverter.
- Apply StreamBinding to the current path tail: x => x.Loader.StreamBinding().
Example fix
// before CompiledBinding.For(x => Helper.Format(x.Name)); // after - expose formatted name on the VM CompiledBinding.For(x => x.FormattedName);
Defensive patterns
Strategy: validation
Validate before calling
// Verify the lambda body chains continuously from its single parameter // (every node's instance resolves to the previous node's result). // Quick check: the body must reference exactly the lambda's parameter as root. var param = expr.Parameters[0]; bool rooted = new RootChecker(param).IsRooted(expr.Body);
Try / catch
try { var path = BindingExpressionVisitor<TIn>.BuildPath<TOut>(expr); }
catch (ExpressionParseException ex) when (ex.Message.Contains("expected an instance of"))
{
// restructure the lambda into a single continuous chain
} Prevention
- Write binding lambdas as one continuous chain from the parameter (x => x.A.B.C).
- Do not call static or instance helpers on objects other than the current path result.
- Apply StreamBinding to the tail of the chain only.
When it happens
Trigger: CompiledBinding.For(x => Helper.Format(x.Name)) where the method operates on a different object than the path head; mixing unrelated sub-expressions; a StreamBinding or delegate call applied to something other than the current path result.
Common situations: Calling static/instance helpers on objects other than the current path result; building expression trees where a node's instance does not chain from the previous node; incorrect StreamBinding placement.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid expression type in binding expression: {node.NodeTyp
- Invalid indexer in binding expression: {node.NodeType}.
- Invalid method call in binding expression: '{node.Method.Dec
- Catch blocks are not allowed in binding expressions.
- Dynamic expressions are not allowed in binding expressions.
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/cb94dc38c717ce10.
Report an issue: GitHub.