AvaloniaUI/Avalonia · error · ExpressionParseException
Invalid indexer in binding expression: {node.NodeType}.
Error message
Invalid indexer in binding expression: {node.NodeType}. What it means
Thrown by BindingExpressionVisitor.VisitIndex when an IndexExpression does not match any of the four supported indexer patterns: (1) AvaloniaObject indexer with an AvaloniaProperty argument, (2) array element access, (3) single-integer-argument indexer with a public getter, or (4) general indexer with a public getter and arbitrary argument types. An indexer that has no GetMethod (write-only) or one whose object and indexer metadata do not satisfy any pattern falls through to this error.
Source
Thrown at src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs:108
info,
(weakRef, propInfo) => CreateIndexerPropertyAccessor(weakRef, propInfo, index)));
}
else if (node.Indexer?.GetMethod is not null)
{
var getMethod = node.Indexer.GetMethod;
var setMethod = node.Indexer?.SetMethod;
var indexes = node.Arguments.Select(GetValue<object>).ToArray();
var info = new ClrPropertyInfo(
CommonPropertyNames.IndexerName,
x => getMethod.Invoke(x, indexes),
setMethod is not null ? (o, v) => setMethod.Invoke(o, indexes.Append(v).ToArray()) : null,
getMethod.ReturnType);
return Add(node.Object, node, x => x.Property(
info,
CreateInpcPropertyAccessor));
}
throw new ExpressionParseException(0, $"Invalid indexer in binding expression: {node.NodeType}.");
}
protected override Expression VisitMember(MemberExpression node)
{
return node.Member.MemberType switch
{
MemberTypes.Property => AddPropertyNode(node),
_ => throw new ExpressionParseException(0, $"Invalid expression type in binding expression: {node.NodeType}."),
};
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
var method = node.Method;
if (method.Name == IndexerGetterName && node.Object is not null)
{
var property = TryGetPropertyFromMethod(method);View on GitHub (pinned to 11c5427268)
Solutions
- Ensure the indexer you bind to has a public getter (get accessor).
- If the type is a dictionary or custom collection, verify the indexer's GetMethod is public and accessible.
- For multi-dimensional arrays, use the dedicated ArrayElement path — verify the expression compiles to a standard array index, not a method call.
Example fix
// before: write-only indexer
public string this[string key] { set { ... } }
// binding:
<TextBlock Text="{CompiledBinding [myKey]}" />
// after: add a public getter
public string this[string key] { get => _dict[key]; set { ... } } Defensive patterns
Strategy: type-guard
Validate before calling
// Check that an indexer has a public getter before using it in a binding
static bool IndexerHasPublicGetter(Type type, Type indexType)
{
foreach (var prop in type.GetDefaultMembers().OfType<PropertyInfo>())
{
if (prop.GetIndexParameters().Length == 1
&& prop.GetIndexParameters()[0].ParameterType == indexType)
return prop.GetMethod?.IsPublic == true;
}
return false;
} Type guard
static bool IsBindableIndexer(IndexExpression node)
{
if (node.Object?.Type.IsArray == true) return true;
if (node.Indexer?.GetMethod?.IsPublic == true) return true;
return false;
} Try / catch
try
{
var path = BindingExpressionVisitor<TViewModel>.BuildPath<TItem>(expr);
}
catch (ExpressionParseException ex) when (ex.Message.Contains("Invalid indexer"))
{
logger.LogError($"Indexer has no public getter or unsupported signature: {ex.Message}");
} Prevention
- Ensure all indexers used in bindings have public get accessors.
- For dictionary bindings, verify the key type matches the indexer parameter type.
- Prefer ObservableCollection<T> and integer indexing for list-style bindings.
When it happens
Trigger: Accessing a write-only indexer (one with a setter but no getter) in a compiled binding lambda; using an indexer on an object whose type metadata is unavailable in the binding context; an IndexExpression constructed manually where node.Indexer is null and node.Object is not an array.
Common situations: Binding to a custom collection whose indexer is write-only; binding to an indexer that takes a non-integer key type where the getter is not public; using a multi-dimensional array indexer that does not match the 'Get' method pattern checked in VisitMethodCall.
Related errors
- Invalid expression type in binding expression: {node.NodeTyp
- 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.
- 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/6d0d3914c9b8b058.
Report an issue: GitHub.