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

  1. Ensure the indexer you bind to has a public getter (get accessor).
  2. If the type is a dictionary or custom collection, verify the indexer's GetMethod is public and accessible.
  3. 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

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


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