AvaloniaUI/Avalonia · error · ExpressionParseException
Unexpected end of expression.
Error message
Unexpected end of expression.
What it means
Thrown by BindingExpressionGrammar.Parse at the end of the main parse loop when the parser is in the BeforeMember or BeforeMemberNullable state. This state means the last token consumed was a member-access operator ('.' or '?.') but no member identifier followed it before the string ended. Avalonia's binding path grammar requires every accessor to be followed by a concrete member name, so a dangling dot is a syntax error.
Source
Thrown at src/Avalonia.Base/Data/Core/Parsers/BindingExpressionGrammar.cs:103
state = ParseElementName(ref r, nodes);
mode = SourceMode.Control;
break;
case State.RelativeSource:
state = ParseRelativeSource(ref r, nodes);
mode = SourceMode.Control;
break;
}
}
if (!r.End)
{
throw new ExpressionParseException(r.Position, "Expected end of expression.");
}
if (state is State.BeforeMember or State.BeforeMemberNullable)
{
throw new ExpressionParseException(r.Position, "Unexpected end of expression.");
}
return mode;
}
private static State ParseStart(ref CharacterReader r, IList<INode> nodes)
{
if (ParseNot(ref r))
{
nodes.Add(new NotNode());
return State.Start;
}
else if (ParseSharp(ref r))
{
return State.ElementName;
}
else if (ParseDollarSign(ref r))View on GitHub (pinned to 11c5427268)
Solutions
- Inspect the binding path string and remove the trailing '.' or '?.', or add the missing member name after it.
- If building paths dynamically, trim trailing accessor operators before passing to the binding system.
- Search the XAML or C# source for the exact binding string reported in the Column property of the exception and verify every '.' or '?.' is followed by an identifier.
Example fix
<!-- before -->
<TextBox Text="{Binding Foo.}" />
<!-- after -->
<TextBox Text="{Binding Foo.Bar}" /> Defensive patterns
Strategy: validation
Validate before calling
// Validate that a binding path string does not end with a member-access operator
static void ValidateBindingPath(string path)
{
if (path.EndsWith('.') || path.EndsWith("?."))
throw new ArgumentException(
$"Binding path '{path}' ends with a member-access operator; a member name is required after '.' or '?.'");
} Try / catch
try
{
var binding = new Binding(path);
}
catch (ExpressionParseException ex)
{
// ex.Column points to the position of the trailing dot
logger.LogError($"Invalid binding path at column {ex.Column}: {ex.Message}");
} Prevention
- Run all binding paths through a unit test that exercises the parser at design time.
- Use source generators or XAML compilation to catch invalid paths at build time rather than runtime.
- Avoid building binding path strings via concatenation; if you must, trim trailing '.' and '?.' characters.
When it happens
Trigger: The binding expression string ends with '.' (e.g. 'Foo.') or '?.' (e.g. 'Foo?.') with no identifier following the operator. Also triggered when dynamic string concatenation appends a trailing dot conditionally, such as $"{path}." where path is the last segment.
Common situations: Incomplete auto-complete in a XAML Binding Path attribute leaving a trailing dot; building binding paths programmatically via StringBuilder or interpolation that conditionally appends '.' on the last segment; copy-paste errors where a property name after the dot was accidentally deleted.
Related errors
- Invalid attached property name.
- Attached Property name expected after '.'.
- Expected ')'.
- Indexer may not be empty.
- Element name expected after '#'.
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/efc4a6e4313dc5c3.
Report an issue: GitHub.