AvaloniaUI/Avalonia · error · ExpressionParseException

Element init expressions are not valid in a binding expressi

Error message

Element init expressions are not valid in a binding expression.

What it means

Thrown unconditionally by BindingExpressionVisitor.VisitElementInit when an ElementInit node appears in the compiled binding expression tree. ElementInit nodes are produced by collection initializer expressions (e.g., 'new List<int> { 1, 2, 3 }'). They have no meaning in a binding property path and are always rejected.

Source

Thrown at src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs:220

    protected override CatchBlock VisitCatchBlock(CatchBlock node)
    {
        throw new ExpressionParseException(0, "Catch blocks are not allowed in binding expressions.");
    }

    protected override Expression VisitConditional(ConditionalExpression node)
    {
        throw new ExpressionParseException(0, $"Invalid expression type in binding expression: {node.NodeType}.");
    }

    protected override Expression VisitDynamic(DynamicExpression node)
    {
        throw new ExpressionParseException(0, "Dynamic expressions are not allowed in binding expressions.");
    }

    protected override ElementInit VisitElementInit(ElementInit node)
    {
        throw new ExpressionParseException(0, "Element init expressions are not valid in a binding expression.");
    }

    protected override Expression VisitGoto(GotoExpression node)
    {
        throw new ExpressionParseException(0, "Goto expressions are not supported in binding expressions.");
    }

    protected override Expression VisitInvocation(InvocationExpression node)
    {
        throw new ExpressionParseException(0, $"Invalid expression type in binding expression: {node.NodeType}.");
    }

    protected override Expression VisitLabel(LabelExpression node)
    {
        throw new ExpressionParseException(0, $"Invalid expression type in binding expression: {node.NodeType}.");
    }

    protected override Expression VisitListInit(ListInitExpression node)

View on GitHub (pinned to 11c5427268)

Solutions

  1. Remove any collection or object initializer syntax from the binding lambda; the lambda should be a simple member-access chain.
  2. If you need to initialize a collection, do so in the view model and bind to the resulting property.
  3. Ensure the binding lambda is a pure property-path expression with no 'new', initializer, or assignment constructs.

Example fix

// before: collection initializer in binding
CompiledBinding(x => new List<string> { x.Name })

// after: bind to a pre-populated property
CompiledBinding(x => x.NameList)
Defensive patterns

Strategy: validation

Validate before calling

// Detect collection initializer expressions in a binding lambda
static bool HasElementInit<TIn, TOut>(Expression<Func<TIn, TOut>> expr)
{
    bool found = false;
    expr.Body.Visit(b =>
    {
        if (b is ListInitExpression or NewArrayExpression) found = true;
    });
    return !found;
}

Try / catch

try
{
    var path = BindingExpressionVisitor<TViewModel>.BuildPath<TProp>(expr);
}
catch (ExpressionParseException ex) when (ex.Message.Contains("Element init"))
{
    logger.LogError("Collection or element initializers are not valid in compiled binding expressions.");
}

Prevention

When it happens

Trigger: Including a collection-initializer expression inside a compiled binding lambda, such as x => new ObservableCollection<int> { 1, 2, 3 }. This is extremely unusual in practice but could arise from copy-pasting initialization code into a binding expression.

Common situations: Accidentally including object or collection initialization syntax in a binding lambda; expression-tree manipulation that injects initializer nodes; generated code from a template engine that includes initializer syntax in what should be a path expression.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/e26a545d28fa6002. Report an issue: GitHub.