dotnet/maui · error · BuildException

XC0040

XC0040

Error message

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

What it means

XC0040 Conversion thrown by EasingTypeConverter when a XAML string does not match any public static field on the Microsoft.Maui.Controls.Easing class. The converter trims the value, optionally strips an 'Easing.' prefix, then resolves the remainder as a static field name (case-insensitive). If no matching static field is found, the build fails.

Source

Thrown at src/Controls/src/Build.Tasks/CompiledConverters/EasingTypeConverter.cs:36

			}

			value = value?.Trim() ?? "";
			var parts = value.Split('.');
			if (parts.Length == 2 && parts[0] == nameof(Easing))
				value = parts[parts.Length - 1];

			var assemblyTypeInfo = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", nameof(Easing));

			var module = context.Body.Method.Module;
			var fieldReference = module.ImportFieldReference(context.Cache, assemblyTypeInfo, value, isStatic: true, caseSensitive: false);

			if (fieldReference != null)
			{
				yield return Create(Ldsfld, fieldReference);
				yield break;
			}

			throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(Easing));
		}
	}
}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Use one of the built-in static fields: SinIn, SinOut, SinInOut, CubicIn, CubicOut, CubicInOut, BounceIn, BounceOut, SpringIn, SpringOut, Linear, QuadraticIn, QuadraticOut, or QuadraticInOut.
  2. The 'Easing.' prefix is optional — 'CubicIn' and 'Easing.CubicIn' are both accepted.
  3. For custom easing functions, set the Easing property in code-behind instead of XAML, since the compiled converter cannot reference arbitrary fields.

Example fix

<!-- before -->
<Animation Easing="ease-in-out" />

<!-- after -->
<Animation Easing="SinInOut" />
<!-- or -->
<Animation Easing="Easing.SinInOut" />
Defensive patterns

Strategy: validation

Validate before calling

// Validate an Easing XAML string against built-in static fields
static readonly HashSet<string> ValidEasings = new(StringComparer.OrdinalIgnoreCase)
{
    "SinIn","SinOut","SinInOut","CubicIn","CubicOut","CubicInOut",
    "BounceIn","BounceOut","SpringIn","SpringOut","Linear",
    "QuadraticIn","QuadraticOut","QuadraticInOut"
};
static bool IsValidEasing(string value)
{
    if (string.IsNullOrWhiteSpace(value)) return false;
    var name = value.Trim();
    if (name.StartsWith("Easing.", StringComparison.OrdinalIgnoreCase))
        name = name["Easing.".Length..];
    return ValidEasings.Contains(name);
}

Prevention

When it happens

Trigger: Assigning an Easing value that is not a known built-in easing function. Examples: Easing="Bounce" (should be BounceIn or BounceOut), Easing="ease-in" (CSS naming), Easing="CustomEasing" (a custom easing field is not supported by the compiled converter — only static fields on the Easing type itself).

Common situations: Confusing CSS easing names (ease-in, ease-out) with MAUI Easing names. Using a custom Easing instance defined in code-behind as a property or local variable — the compiled converter can only reference static fields on the Easing type. Misspelling a known easing name.

Related errors


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