dotnet/maui · error · BuildException

XC0040

XC0040

Error message

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

What it means

XC0040 Conversion thrown by StrokeShapeTypeConverter when the XAML string does not match any recognized shape keyword and is not a plain number. Recognized keywords (case-sensitive StartsWith) are: Ellipse, Line, Path, Polygon, Polyline, Rectangle, RoundRectangle. A plain number is interpreted as a uniform corner radius for a RoundRectangle. If none match, the build fails with target type IShape.

Source

Thrown at src/Controls/src/Build.Tasks/CompiledConverters/StrokeShapeTypeConverter.cs:213

				yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "Rectangle"), parameterTypes: null));
				yield return Instruction.Create(OpCodes.Dup);

				yield return Instruction.Create(OpCodes.Ldc_R8, radius);
				yield return Instruction.Create(OpCodes.Ldc_R8, radius);
				yield return Instruction.Create(OpCodes.Ldc_R8, radius);
				yield return Instruction.Create(OpCodes.Ldc_R8, radius);

				yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "CornerRadius"), parameterTypes: new[] {
					("mscorlib", "System", "Double"),
					("mscorlib", "System", "Double"),
					("mscorlib", "System", "Double"),
					("mscorlib", "System", "Double")}));

				yield return Instruction.Create(OpCodes.Call, module.ImportPropertySetterReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Shapes", "RoundRectangle"), "CornerRadius"));
				yield break;
			}
		}
		throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(IShape));
	}

	IEnumerable<Instruction> CreatePointCollection(ILContext context, ModuleDefinition module, PointCollection points)
	{
		var pointType = module.ImportReference(context.Cache, ("Microsoft.Maui.Graphics", "Microsoft.Maui.Graphics", "Point"));
		yield return Instruction.Create(OpCodes.Ldc_I4, points.Count);
		yield return Instruction.Create(OpCodes.Newarr, pointType);

		var pointTypeConverter = new PointTypeConverter();
		for (int i = 0; i < points.Count; i++)
		{
			yield return Instruction.Create(OpCodes.Dup);
			yield return Instruction.Create(OpCodes.Ldc_I4, i);

			foreach (var instruction in pointTypeConverter.CreatePoint(context, module, points[i]))
			{
				yield return instruction;
			}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Use one of the recognized shape keywords: Ellipse, Line, Path, Polygon, Polyline, Rectangle, or RoundRectangle (case-sensitive).
  2. For RoundRectangle with a corner radius, use 'RoundRectangle CornerRadius' syntax or a plain number for uniform radius.
  3. Ensure the keyword prefix matches exactly (uppercase first letter as shown).

Example fix

<!-- before -->
<Border StrokeShape="Circle" />

<!-- after -->
<Border StrokeShape="Ellipse" />
<!-- or -->
<Border StrokeShape="RoundRectangle 10" />
Defensive patterns

Strategy: validation

Validate before calling

// Validate a StrokeShape XAML string before building
static readonly string[] ValidShapePrefixes =
    { "Ellipse", "Line", "Path", "Polygon", "Polyline", "Rectangle", "RoundRectangle" };
static bool IsValidStrokeShape(string value)
{
    if (string.IsNullOrWhiteSpace(value)) return false;
    value = value.Trim();
    if (ValidShapePrefixes.Any(p => value.StartsWith(p, StringComparison.Ordinal)))
        return true;
    return double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out _);
}

Prevention

When it happens

Trigger: Setting Border.StrokeShape or a Shape property to an unrecognized shape name, a misspelled keyword, or empty/whitespace. Examples: 'RoundRectangle ' (empty after keyword is handled differently), 'Circle' (should be 'Ellipse'), 'Triangle' (not a built-in shape — use Path or Polygon), 'roundrect' (case-sensitive prefix).

Common situations: Using 'Circle' instead of 'Ellipse'. Using lowercase shape names ('roundrectangle' vs 'RoundRectangle'). Forgetting to include any shape keyword. The value is case-sensitive — the converter uses StartsWith with Ordinal comparison.

Related errors


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