dotnet/maui · error · BuildException

XC0042

XC0042

Error message

Binding: Indexer did not contain arguments.

What it means

Thrown when an indexer in a compiled-binding path has brackets but the argument length between them is zero (i.e. `[]`). The compiler computes argLength = rbIndex - lbIndex - 1 and throws BindingIndexerEmpty when it is 0.

Source

Thrown at src/Controls/src/Build.Tasks/SetPropertiesVisitor.cs:835

			path = path.Trim(' ', '.'); //trim leading or trailing dots
			var parts = path.Split(['.'], StringSplitOptions.RemoveEmptyEntries);
			var properties = new List<(PropertyDefinition property, TypeReference propDeclTypeRef, string indexArg)>();

			var previousPartTypeRef = tSourceRef;
			foreach (var part in parts)
			{
				var p = part;
				string indexArg = null;
				var lbIndex = p.IndexOf('[');
				if (lbIndex != -1)
				{
					var rbIndex = p.LastIndexOf(']');
					if (rbIndex == -1)
						throw new BuildException(BindingIndexerNotClosed, lineInfo, null);

					var argLength = rbIndex - lbIndex - 1;
					if (argLength == 0)
						throw new BuildException(BindingIndexerEmpty, lineInfo, null);

					indexArg = p.Substring(lbIndex + 1, argLength).Trim();
					if (indexArg.Length == 0)
						throw new BuildException(BindingIndexerEmpty, lineInfo, null);

					p = p.Substring(0, lbIndex);
					p = p.Trim();
				}

				if (p.Length > 0)
				{
					var property = previousPartTypeRef.GetProperty(context.Cache, pd => pd.Name == p && pd.GetMethod != null && pd.GetMethod.IsPublic && !pd.GetMethod.IsStatic, out var propDeclTypeRef);
					if (property is null)
					{
						// When the source type was inferred from RelativeSource AncestorType (rather
						// than an explicit x:DataType), a missing property doesn't necessarily mean the
						// binding is invalid - the actual runtime ancestor may be a subtype that declares
						// the property. Silently fall back to a regular (reflection-based) Binding instead

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Provide a concrete index argument inside the brackets.
  2. If indexing is not intended, remove the brackets entirely.
  3. Verify the argument matches the indexer key type (int/string/enum).

Example fix

<!-- before -->
<Label Text="{Binding Items[]}" />

<!-- after -->
<Label Text="{Binding Items[0]}" />
Defensive patterns

Strategy: validation

Validate before calling

// Reject empty indexer brackets
static bool IndexersHaveContent(string path) =>
    !path.Split('.').Any(seg => seg.Contains("[]"));

Prevention

When it happens

Trigger: A binding path indexer with no argument at all, e.g. `{Binding Items[]}`.

Common situations: Typing empty brackets while sketching a binding; leftover placeholder after refactoring.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/8548499e14f186c4. Report an issue: GitHub.