dotnet/maui · error · BuildException

XC0062

XC0062

Error message

Undeclared xmlns prefix "{0}".

What it means

Thrown when a markup expression uses an XML namespace prefix that is not declared on any ancestor element. The parser looks up the prefix via nsResolver.LookupNamespace; if the prefix is non-empty but resolves to an empty URI, the type cannot be located and the build aborts.

Source

Thrown at src/Controls/src/Build.Tasks/ExpandMarkupsVisitor.cs:132

			public INode Parse(string match, ref string remaining, IServiceProvider serviceProvider)
			{
				if (!(serviceProvider.GetService(typeof(IXmlNamespaceResolver)) is IXmlNamespaceResolver nsResolver))
					throw new ArgumentException();
				IXmlLineInfo xmlLineInfo = null;
				if (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) is IXmlLineInfoProvider xmlLineInfoProvider)
					xmlLineInfo = xmlLineInfoProvider.XmlLineInfo;
				var contextProvider = serviceProvider.GetService(typeof(ILContextProvider)) as ILContextProvider;

				var split = match.Split(':');
				if (split.Length > 2)
					throw new ArgumentException();

				var (prefix, name) = ParseName(match);

				var namespaceuri = nsResolver.LookupNamespace(prefix) ?? "";
				if (!string.IsNullOrEmpty(prefix) && string.IsNullOrEmpty(namespaceuri))
					throw new BuildException(BuildExceptionCode.XmlnsUndeclared, xmlLineInfo, null, prefix);

				IList<XmlType> typeArguments = null;
				var childnodes = new List<(XmlName, INode)>();
				var contentname = new XmlName(null, null);

				if (remaining.StartsWith("}", StringComparison.Ordinal))
				{
					remaining = remaining.Substring(1);
				}
				else
				{
					Property parsed;
					do
					{
						try
						{
							parsed = ParseProperty(serviceProvider, ref remaining);
						}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Declare the missing xmlns prefix on the root element, e.g. xmlns:local="clr-namespace:MyApp.Controls".
  2. Correct the prefix spelling to match the declaration.
  3. Move the xmlns declaration to a common ancestor that is in scope for the expression.

Example fix

// before
<ContentPage>   <!-- no xmlns:local -->
  <Label Text="{local:Tr Key=Hello}" />
</ContentPage>
// after
<ContentPage xmlns:local="clr-namespace:MyApp.Markup">
  <Label Text="{local:Tr Key=Hello}" />
</ContentPage>
Defensive patterns

Strategy: validation

Validate before calling

// Collect declared xmlns prefixes from the root and check usage
static ISet<string> DeclaredPrefixes(XDocument doc) =>
    doc.Root!.Attributes()
       .Where(a => a.Name.NamespaceName == "http://www.w3.org/2000/xmlns/")
       .Select(a => a.Name.LocalName).ToHashSet();

static bool AllMarkupPrefixesDeclared(XDocument doc, ISet<string> prefixes) {
    // naive: scan attribute values for '{prefix:' patterns
    var used = Regex.Matches(doc.ToString(), @"\{(\w+):").Select(m => m.Groups[1].Value);
    return used.All(prefixes.Contains);
}

Prevention

When it happens

Trigger: Writing '{local:MyExtension ...}' without xmlns:local declared on the root; typo in the prefix (e.g. 'loc' vs 'local'); prefix declared in a sibling scope but used outside it.

Common situations: Renaming an xmlns prefix in the root but not updating usage; copying XAML snippets between files that have different prefix mappings; declaring the xmlns on a child element where it is not in scope for the binding.

Related errors


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