AvaloniaUI/Avalonia · error · ExpressionParseException
Catch blocks are not allowed in binding expressions.
Error message
Catch blocks are not allowed in binding expressions.
What it means
Thrown unconditionally by BindingExpressionVisitor.VisitCatchBlock whenever a CatchBlock node appears in the expression tree. Catch blocks are produced by try-catch expressions in statement lambdas. Since compiled bindings represent a declarative property path, exception handling constructs are never valid.
Source
Thrown at src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs:205
return Add(node.Operand, node, x => x.TypeCast(node.Type));
}
}
else if (node.NodeType == ExpressionType.TypeAs)
{
return Add(node.Operand, node, x => x.TypeCast(node.Type));
}
throw new ExpressionParseException(0, $"Invalid expression type in binding expression: {node.NodeType}.");
}
protected override Expression VisitBlock(BlockExpression node)
{
throw new ExpressionParseException(0, $"Invalid expression type in binding expression: {node.NodeType}.");
}
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)View on GitHub (pinned to 11c5427268)
Solutions
- Use the binding's FallbackValue or TargetNullValue to handle null or error results instead of try-catch.
- Use the null-conditional operator (x?.Y) in the lambda for null-safe property access.
- Move any exception-handling logic into a view-model property and bind to that property.
Example fix
// before: try-catch in compiled binding
CompiledBinding(x => { try { return x.MightBeNull.Name; } catch { return ""; } })
// after: null-conditional + FallbackValue
<TextBlock Text="{CompiledBinding MightBeNull?.Name, FallbackValue=N/A}" /> Defensive patterns
Strategy: validation
Validate before calling
// Detect try-catch usage in a binding lambda at design time
static bool HasTryCatch<TIn, TOut>(Expression<Func<TIn, TOut>> expr)
{
bool found = false;
expr.Body.Visit(b =>
{
if (b is TryExpression) found = true;
});
return found;
} Try / catch
try
{
var path = BindingExpressionVisitor<TViewModel>.BuildPath<TProp>(expr);
}
catch (ExpressionParseException ex) when (ex.Message.Contains("Catch blocks"))
{
logger.LogError("Try-catch is not allowed in compiled binding expressions. Use FallbackValue or null-conditional access.");
} Prevention
- Never use try-catch in a compiled binding lambda.
- Use the binding's FallbackValue for error recovery.
- Use null-conditional access (x?.Y) for null safety instead of try-catch.
When it happens
Trigger: Using a try-catch inside a statement lambda in a compiled binding: x => { try { return x.Risky; } catch { return null; } } produces a TryExpression containing CatchBlock nodes that trigger this error when visited.
Common situations: Attempting to handle null-reference or conversion exceptions inline within the binding expression; wrapping risky property access in try-catch instead of using the binding's FallbackValue or null-conditional operator; migrating error-handling code-behind into a binding lambda.
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
- Dynamic expressions are not allowed in binding expressions.
- Element init expressions are not valid in a binding expressi
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/4837e337788a374d.
Report an issue: GitHub.