dotnet/maui · error · BuildException

XC0040

XC0040

Error message

Cannot convert value "{0}" to "{1}".

What it means

XamlC error XC0040 from BindablePropertyConverter. The converter splits the XAML value on '.' and accepts exactly 1 segment (property name, type inferred from context) or 2 segments (Type.Property). More than two dot-separated segments cannot be interpreted, so it throws a conversion (XC0040) error.

Source

Thrown at src/Controls/src/Build.Tasks/CompiledConverters/BindablePropertyConverter.cs:61

					else if (parent.XmlType.IsOfAnyType(nameof(VisualState)))
					{
						typeName = FindTypeNameForVisualState(parent, node, context);
					}
				}
				else if (node.Parent is ElementNode { XmlType: XmlType xt1 } && xt1.IsOfAnyType(nameof(Trigger)))
				{
					typeName = GetTargetTypeName(node.Parent);
				}
				propertyName = parts[0];
			}
			else if (parts.Length == 2)
			{
				var targetType = parts[0];
				typeName = TypeArgumentsParser.ParseSingle(targetType, node.NamespaceResolver, (IXmlLineInfo)node);
				propertyName = parts[1];
			}
			else
				throw new BuildException(Conversion, node, null, value, typeof(BindableProperty));

			if (typeName == null || propertyName == null)
				throw new BuildException(Conversion, node, null, value, typeof(BindableProperty));

			var typeRef = typeName.GetTypeReference(context.Cache, module, node);
			if (typeRef == null)
				throw new BuildException(TypeResolution, node, null, typeName);

			bpRef = GetBindablePropertyFieldReference(context.Cache, typeRef, propertyName, module);
			if (bpRef == null)
				throw new BuildException(PropertyResolution, node, null, propertyName, typeRef.Name);
			return bpRef;

			static XmlType GetTargetTypeName(INode node)
			{
				var targetType = ((node as ElementNode).Properties[new XmlName("", "TargetType")] as ValueNode)?.Value as string;
				return TypeArgumentsParser.ParseSingle(targetType, node.NamespaceResolver, (IXmlLineInfo)node);
			}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Declare an xmlns prefix and use exactly Type.Property (two segments), e.g. local:MyView.SpacingProperty.
  2. If only the property name is needed, place the setter inside a Style/Trigger/VisualState that has a TargetType so the type is inferred (single segment).

Example fix

<!-- before -->
<Setter Property="MyLib.Controls.MyView.SpacingProperty" Value="10" />

<!-- after -->
xmlns:local="clr-namespace:MyLib.Controls"
<Setter Property="local:MyView.SpacingProperty" Value="10" />
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: A value with three or more dot-segments is used where a BindableProperty is expected — e.g. a full namespace like 'MyLib.Controls.MyView.SomeProperty' or 'Foo.Bar.Baz' in a Setter.Property.

Common situations: Typing a fully-qualified namespace instead of using an xmlns prefix; referencing a nested type through multiple namespace dots; mis-pasting a type path.

Related errors


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