dotnet/maui · error · BuildException
XC0040
XC0040
Error message
Cannot convert value "{0}" to "{1}". What it means
Thrown by NodeILExtensions.TryFormat when converting a XAML literal string to a target type (via Parse/TryParse-style func) raises a FormatException. The XAML compiler attempts to convert inline literals (numbers, enums, GUIDs, etc.) to the property's type and reports the offending value and target type.
Source
Thrown at src/Controls/src/Build.Tasks/NodeILExtensions.cs:142
var typeConverter = bpRef.GetBindablePropertyTypeConverter(context.Cache, module);
//we're gonna SetValue. if the BP type is Nullable, we only need to convert/box to the non-nullable type? why, because the CSC compiler does it like that
if (targetTypeRef.ResolveCached(context.Cache).FullName == "System.Nullable`1")
targetTypeRef = ((GenericInstanceType)targetTypeRef).GenericArguments[0];
return node.PushConvertedValue(context, targetTypeRef, typeConverter, pushServiceProvider, boxValueTypes,
unboxValueTypes);
}
static T TryFormat<T>(Func<string, T> func, IXmlLineInfo lineInfo, string str)
{
try
{
return func(str);
}
catch (FormatException fex)
{
throw new BuildException(BuildExceptionCode.Conversion, lineInfo, fex, str, typeof(T));
}
}
public static IEnumerable<Instruction> PushConvertedValue(this ValueNode node, ILContext context,
TypeReference targetTypeRef, TypeReference typeConverter, Func<TypeReference[], IEnumerable<Instruction>> pushServiceProvider,
bool boxValueTypes, bool unboxValueTypes)
{
var module = context.Body.Method.Module;
var knownCompiledTypeConverters = context.Cache.GetKnownCompiledTypeConverters(module);
var str = (string)node.Value;
//If the TypeConverter has a ProvideCompiledAttribute that can be resolved, shortcut this
Type compiledConverterType;
if (typeConverter?.GetCustomAttribute(context.Cache, module, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "ProvideCompiledAttribute"))?.ConstructorArguments?.First().Value is string compiledConverterName
&& (compiledConverterType = Type.GetType(compiledConverterName)) != null
|| (typeConverter != null && knownCompiledTypeConverters.TryGetValue(typeConverter, out compiledConverterType)))
{
var compiledConverter = Activator.CreateInstance(compiledConverterType);View on GitHub (pinned to f377ff1c5e)
Solutions
- Use the literal format the target type's Parse expects (e.g. '.' decimal separator for double).
- For enums, use the exact member name (case-sensitive).
- Strip units or use a TypeConverter-aware syntax for unitized values.
- If the value must be dynamic, bind it rather than inlining a literal.
Example fix
// before <Frame Opacity="1,5" /> <!-- comma in invariant culture --> // after <Frame Opacity="1.5" />
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate a literal against the target type's Parse (invariant culture)
static bool CanConvert<T>(string literal) {
try { _ = (T)System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(null, System.Globalization.CultureInfo.InvariantCulture, literal); return true; }
catch { return false; }
} Try / catch
// If you author a custom TypeConverter's compiled path, wrap Parse in TryFormat-style guard
try { return func(str); }
catch (FormatException fex) {
throw new BuildException(BuildExceptionCode.Conversion, lineInfo, fex, str, typeof(T));
} Prevention
- Use the invariant (en-US) literal format: '.' decimals, exact enum names.
- Avoid unit suffixes on properties without a TypeConverter for them.
- Bind dynamic values instead of inlining literals that need parsing.
When it happens
Trigger: Setting a numeric property to a non-numeric string; an enum property set to an undefined member; a GUID/DateTime property with a malformed literal; locale-specific number separators that Parse rejects.
Common situations: Typing a value like Opacity="1,5" in a comma-decimal locale where '.' is expected; misspelling an enum value; passing a string where a typed converter expects a specific format; unit suffixes like '10px' on a double property.
Related errors
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/917fba8edb63386a.
Report an issue: GitHub.