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
- Declare the missing xmlns prefix on the root element, e.g. xmlns:local="clr-namespace:MyApp.Controls".
- Correct the prefix spelling to match the declaration.
- 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
- Declare every xmlns prefix you reference on the root element.
- Keep prefix names consistent across files via shared templates.
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.