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
- Declare an xmlns prefix and use exactly Type.Property (two segments), e.g. local:MyView.SpacingProperty.
- 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
- Use an xmlns prefix and limit BindableProperty values to one or two dot-segments.
- Never paste a fully-qualified namespace into a BindableProperty value; declare an xmlns instead.
- Place context-dependent single-name properties inside a Style/Trigger/VisualState with a TargetType.
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.