dotnet/wpf · error · XamlSchemaException
SR.BadXmlnsCompat
Error message
SR.BadXmlnsCompat
What it means
System.Xaml throws XamlSchemaException(SR.BadXmlnsCompat) while loading [assembly: XmlnsCompat] attributes when either the old or new CLR namespace string is null or empty. The attribute is used to map old namespaces to new ones for forward compatibility, so both values must be non-empty to build the mapping.
Solutions
- Fill in both the old and new CLR namespace strings in the XmlnsCompat attribute.
- Remove the XmlnsCompat attribute entirely if no namespace mapping is intended.
- Verify the constants used for the attribute values are non-empty at compile time.
Example fix
// before
[assembly: System.Windows.Markup.XmlnsCompat("", "clr-namespace:NewNs")]
// after
[assembly: System.Windows.Markup.XmlnsCompat("clr-namespace:OldNs", "clr-namespace:NewNs")] Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(oldNs) || string.IsNullOrEmpty(newNs)) throw new InvalidOperationException("XmlnsCompat requires non-empty old and new namespaces"); Try / catch
try { loader.Load(stream); } catch (XamlSchemaException ex) when (ex.Message.Contains("XmlnsCompat")) { /* fix assembly attributes */ } Prevention
- Use const strings for namespace values so emptiness is caught at compile time
- Review AssemblyInfo attributes after every namespace refactor
When it happens
Trigger: An assembly declares [assembly: XmlnsCompat("clr-namespace:OldNs", "", typeof(...))] or omits one of the namespace strings; LoadOldToNewNs -> LoadOldToNewNsHelper then encounters an empty oldns/newns while building the xmlns compat dictionary.
Common situations: Hand-written assembly attributes after a namespace refactor, typos leaving one argument empty, code-generated attributes where a namespace constant resolved to empty string.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- SR.BadXmlnsPrefix
- ArgumentNullException(nameof(clrNamespace))
- MappingParseError(_scanner.Start, token, _token)
- SR.DuplicateXmlnsCompat
- SR.DuplicateXmlnsCompatAcrossAssemblies
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/af17ebde15000b5c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/MS/Impl/XmlNsInfo.cs:344
else
{
Attribute[] attributes = Attribute.GetCustomAttributes(assembly, typeof(XmlnsCompatibleWithAttribute));
foreach (Attribute attr in attributes)
{
// Read in the attribute value
XmlnsCompatibleWithAttribute xmlnsCompatAttr = (XmlnsCompatibleWithAttribute)attr;
LoadOldToNewNsHelper(result, xmlnsCompatAttr.OldNamespace, xmlnsCompatAttr.NewNamespace, assembly);
}
}
return result;
}
private void LoadOldToNewNsHelper(Dictionary<string, string> result, string oldns, string newns, Assembly assembly)
{
if (string.IsNullOrEmpty(newns) || string.IsNullOrEmpty(oldns))
{
throw new XamlSchemaException(SR.Format(SR.BadXmlnsCompat, assembly.FullName));
}
if (result.ContainsKey(oldns))
{
throw new XamlSchemaException(SR.Format(SR.DuplicateXmlnsCompat, assembly.FullName, oldns));
}
result.Add(oldns, newns);
}
private Dictionary<string, string> LoadPrefixes()
{
Dictionary<string, string> result = new Dictionary<string, string>(StringComparer.Ordinal);
Assembly assembly = Assembly;
if (assembly is null)
{
return result;View on GitHub (pinned to 81131a70a4)