dotnet/maui · error · BuildException

XC0040

XC0040

Error message

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

What it means

XC0040 Conversion thrown by CornerRadiusTypeConverter when a XAML string value cannot be parsed into a Microsoft.Maui.CornerRadius during XAML compilation. The converter splits the string on commas and accepts exactly 1 value (uniform radius) or 4 values (top-left, top-right, bottom-left, bottom-right), each parsed as an invariant-culture double. If the split yields a count other than 1 or 4, or any segment fails double.TryParse, the exception fires.

Source

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

			{
				double l, tl, tr, bl, br;
				var cornerradius = value.Split(',');
				switch (cornerradius.Length)
				{
					case 1:
						if (double.TryParse(cornerradius[0], NumberStyles.Number, CultureInfo.InvariantCulture, out l))
							return GenerateIL(context, module, l);
						break;
					case 4:
						if (double.TryParse(cornerradius[0], NumberStyles.Number, CultureInfo.InvariantCulture, out tl)
							&& double.TryParse(cornerradius[1], NumberStyles.Number, CultureInfo.InvariantCulture, out tr)
							&& double.TryParse(cornerradius[2], NumberStyles.Number, CultureInfo.InvariantCulture, out bl)
							&& double.TryParse(cornerradius[3], NumberStyles.Number, CultureInfo.InvariantCulture, out br))
							return GenerateIL(context, module, tl, tr, bl, br);
						break;
				}
			}
			throw new BuildException(BuildExceptionCode.Conversion, node, null, value, typeof(CornerRadius));
		}

		IEnumerable<Instruction> GenerateIL(ILContext context, ModuleDefinition module, params double[] args)
		{
			foreach (var d in args)
				yield return Instruction.Create(OpCodes.Ldc_R8, d);
			yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(context.Cache, ("Microsoft.Maui", "Microsoft.Maui", "CornerRadius"), parameterTypes: args.Select(a => ("mscorlib", "System", "Double")).ToArray()));
		}
	}

}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Provide exactly 1 value for a uniform radius or exactly 4 comma-separated values in order: topLeft, topRight, bottomLeft, bottomRight.
  2. Remove any non-numeric characters, spaces inside segments, or stray delimiters from the value.
  3. If you need different horizontal/vertical radii, note that CornerRadius does not support that shape — use 4 corner values instead.

Example fix

<!-- before -->
<Border StrokeShape="RoundRectangle 10,20">
  <Border.CornerRadius>10,20</Border.CornerRadius>
</Border>

<!-- after -->
<Border StrokeShape="RoundRectangle 10,10,10,10">
  <Border.CornerRadius>10,20,10,20</Border.CornerRadius>
</Border>
Defensive patterns

Strategy: validation

Validate before calling

// Validate a CornerRadius XAML string before building
static bool IsValidCornerRadius(string value)
{
    if (string.IsNullOrWhiteSpace(value)) return false;
    var parts = value.Trim().Split(',');
    if (parts.Length != 1 && parts.Length != 4) return false;
    return parts.All(p => double.TryParse(p.Trim(), NumberStyles.Number, CultureInfo.InvariantCulture, out _));
}

Prevention

When it happens

Trigger: Setting CornerRadius (e.g. on a Border, Frame, or RoundRectangle shape) to a comma-separated string with 2 or 3 segments, a non-numeric segment, or using a locale-specific decimal separator. Example: CornerRadius="10,20" (only 2 values), CornerRadius="1,2,3" (3 values), CornerRadius="1.5x,2" (typo).

Common situations: Developers confuse CornerRadius (1 or 4 values) with Thickness (1, 2, or 4 values) and write two-value shorthand like '10,20'. Using a comma decimal separator in a non-invariant locale does not cause issues (InvariantCulture is used) but spaces inside segments like '1 0, 2 0' will. Copying CSS-style values or mixing up corner order with Thickness order.

Related errors


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