dotnet/maui · error · BuildException

XC0020

XC0020

Error message

The name of the BindableProperty {0} does not end with "Property".

What it means

XAML compiler (XamlC) validation, error XC0020. Every Maui BindableProperty field must follow the naming convention <Name>Property. GetBindablePropertyType checks the referenced field name ends with 'Property' and throws XC0020 if it does not, because the suffix is how XamlC derives the CLR property name to read the property's type.

Source

Thrown at src/Controls/src/Build.Tasks/BindablePropertyReferenceExtensions.cs:14

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Mono.Cecil;

namespace Microsoft.Maui.Controls.Build.Tasks
{
	static class BindablePropertyReferenceExtensions
	{
		public static TypeReference GetBindablePropertyType(this FieldReference bpRef, XamlCache cache, IXmlLineInfo iXmlLineInfo, ModuleDefinition module)
		{
			if (!bpRef.Name.EndsWith("Property", StringComparison.InvariantCulture))
				throw new BuildException(BuildExceptionCode.BPName, iXmlLineInfo, null, bpRef.Name);
			var bpName = bpRef.Name.Substring(0, bpRef.Name.Length - 8);
			var owner = bpRef.DeclaringType;

			var getter = owner.GetProperty(cache, pd => pd.Name == bpName, out TypeReference declaringTypeRef)?.GetMethod;
			if (getter == null || getter.IsStatic || !getter.IsPublic)
				getter = null;
			getter = getter ?? owner.GetMethods(cache, md => md.Name == $"Get{bpName}" &&
												md.IsStatic &&
												md.IsPublic &&
												md.Parameters.Count == 1 &&
												md.Parameters[0].ParameterType.InheritsFromOrImplements(cache, module.ImportReference(cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))), module).FirstOrDefault()?.Item1;
			if (getter == null)
				throw new BuildException(BuildExceptionCode.BPName, iXmlLineInfo, null, bpName, bpRef.DeclaringType);

			return getter.ResolveGenericReturnType(declaringTypeRef, module);
		}

		public static TypeReference GetBindablePropertyTypeConverter(this FieldReference bpRef, XamlCache cache, ModuleDefinition module)

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Use the BindableProperty field name with the 'Property' suffix (e.g. SpacingProperty, not Spacing).
  2. Verify the field is actually a public static BindableProperty on the referenced type.
  3. Double-check spelling against the type's documented BindableProperty fields.

Example fix

<!-- before -->
<Setter Property="Spacing" Value="10" />

<!-- after -->
<Setter Property="SpacingProperty" Value="10" />
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: XAML sets an attribute (typically a Setter.Property or an attached-property usage) to a static field whose name does not end with 'Property' — e.g. using the CLR property name 'Spacing' where the 'SpacingProperty' field is required, or pointing at a non-BindableProperty static field.

Common situations: Typing the CLR wrapper name instead of the field; referencing a plain static field that is not a BindableProperty; copy-paste typos in property names.

Related errors


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