dotnet/maui · error · BuildException
XC0003
XC0003
Error message
Missing mandatory property "{0}" on "{1}". What it means
Thrown by the compiled x:Type extension when the TypeName property (or the single inline collection item) is not a string literal ValueNode. x:Type needs a concrete type name string to import and emit a Type token; a missing or non-literal value makes emission impossible.
Source
Thrown at src/Controls/src/Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs:23
using Mono.Cecil;
using Mono.Cecil.Cil;
using static Mono.Cecil.Cil.Instruction;
using static Mono.Cecil.Cil.OpCodes;
namespace Microsoft.Maui.Controls.Build.Tasks
{
class TypeExtension : ICompiledMarkupExtension
{
public IEnumerable<Instruction> ProvideValue(ElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef)
{
memberRef = module.ImportReference(context.Cache, ("mscorlib", "System", "Type"));
var name = new XmlName("", "TypeName");
if (!node.Properties.TryGetValue(name, out INode typeNameNode) && node.CollectionItems.Any())
typeNameNode = node.CollectionItems[0];
if (!(typeNameNode is ValueNode valueNode))
throw new BuildException(BuildExceptionCode.PropertyMissing, node as IXmlLineInfo, null, "TypeName", typeof(Microsoft.Maui.Controls.Xaml.TypeExtension));
if (!node.Properties.ContainsKey(name))
{
node.Properties[name] = typeNameNode;
node.CollectionItems.Clear();
}
var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, valueNode.Value as string, module, node as BaseNode));
context.TypeExtensions[node] = typeref ?? throw new BuildException(BuildExceptionCode.TypeResolution, node as IXmlLineInfo, null, valueNode.Value);
return new List<Instruction> {
Create(Ldtoken, module.ImportReference(typeref)),
Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"),
methodName: "GetTypeFromHandle",
parameterTypes: [("mscorlib", "System", "RuntimeTypeHandle")],
isStatic: true)),
};View on GitHub (pinned to f377ff1c5e)
Solutions
- Provide TypeName="MyNamespace.MyType" as an attribute, or put the type name as inline text content.
- Ensure the xmlns prefix for the type's namespace is declared and used, e.g. TypeName="local:MyView".
- Verify the value is a plain string literal, not a nested element/marker.
- If the type must be dynamic, do not use x:Type in compiled XAML; resolve it in code-behind.
Example fix
// before <DataTemplate> <x:Type /> </DataTemplate> // after <DataTemplate> <x:Type TypeName="local:MyView" /> </DataTemplate>
Defensive patterns
Strategy: validation
Validate before calling
// Ensure x:Type has a literal TypeName
static bool XTypeHasLiteralTypeName(XElement el) =>
el.Attribute("TypeName") is { Value: { Length: > 0 } v }
|| (!el.Elements().Any() && !string.IsNullOrWhiteSpace(el.Value)); Prevention
- Always provide TypeName="..." on x:Type with a declared xmlns prefix.
- Avoid nesting markup inside x:Type; use a literal name only.
- Resolve types dynamically in code-behind instead of compiled XAML.
When it happens
Trigger: Using <x:Type /> with no TypeName attribute and no inline text; binding TypeName to another markup extension or element node instead of a literal; whitespace-only content that fails the ValueNode cast.
Common situations: Authoring a DataTemplate or Style TargetType via x:Type and forgetting the type name; attempting to compute the type dynamically at build time; malformed XAML where the closing tag swallows the text.
Related errors
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/8ce639aced799e1d.
Report an issue: GitHub.