dotnet/wpf · error · XamlSchemaException
SR.XmlnsCompatCycle
Error message
SR.XmlnsCompatCycle
What it means
System.Xaml throws XamlSchemaException(SR.XmlnsCompatCycle) when the old-to-new namespace mapping defined by XmlnsCompat attributes contains a cycle (e.g. nsA -> nsB -> nsA). NamespaceComparer walks the chain to compute transitive subsumption counts and detects a repeated namespace via the visited set.
Solutions
- Break the cycle by removing or correcting one XmlnsCompat mapping so the chain is acyclic and ends at the current namespace.
- Keep only mappings that point strictly from older to newer namespaces, one direction only.
- Audit all assemblies' XmlnsCompat attributes after namespace migrations for conflicting directions.
Example fix
// before (cycle)
[assembly: XmlnsCompat("clr-namespace:A", "clr-namespace:B")]
[assembly: XmlnsCompat("clr-namespace:B", "clr-namespace:A")]
// after (acyclic)
[assembly: XmlnsCompat("clr-namespace:A", "clr-namespace:B")] Defensive patterns
Strategy: validation
Validate before calling
var map = new Dictionary<string,string> { ["clr-namespace:A"]="clr-namespace:B" }; var seen = new HashSet<string>(); var ns = startNs; while (ns != null && map.ContainsKey(ns)) { if (!seen.Add(ns)) throw new InvalidOperationException("XmlnsCompat cycle at " + ns); ns = map[ns]; } Try / catch
try { loadXaml(); } catch (XamlSchemaException ex) when (ex.Message.Contains("XmlnsCompatCycle")) { /* remove the cyclic mapping */ } Prevention
- Always map old -> newer namespaces in a single direction only
- Remove obsolete compat attributes once the old namespace is gone
When it happens
Trigger: Assembly-level XmlnsCompat attributes form a loop such that GetNewNs(ns) eventually returns a namespace already visited; encountered in NamespaceComparer while ordering namespaces.
Common situations: Namespace refactors done in both directions (A->B and B->A attributes kept simultaneously), merged assembly attributes from different branches each mapping the namespaces toward their own version.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- SR.BadXmlnsCompat
- SR.BadXmlnsPrefix
- SR.DuplicateXmlnsCompat
- SR.DuplicateXmlnsCompatAcrossAssemblies
- ' '.' ' is a property without a getter and is not a valid…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/984c661afba554c5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/MS/Impl/XmlNsInfo.cs:473
_nsInfo = nsInfo;
// Calculate the subsume count upfront, since this also serves as our cycle detection
_subsumeCount = new Dictionary<string, int>(nsInfo.OldToNewNs.Count);
HashSet<string> visited = new HashSet<string>();
// for every XmlnsCompatAttribute
foreach (string newNs in nsInfo.OldToNewNs.Values)
{
visited.Clear();
// Increment the subsume count for all transitive subsumers
string ns = newNs;
do
{
if (!visited.Add(ns))
{
throw new XamlSchemaException(SR.Format(SR.XmlnsCompatCycle, assembly.FullName, ns));
}
IncrementSubsumeCount(ns);
ns = GetNewNs(ns);
}
while (ns is not null);
}
}
public int CompareNamespacesByPreference(string ns1, string ns2)
{
if (KS.Eq(ns1, ns2))
{
return 0;
}
const int Prefer_NS1 = -1;
const int Prefer_NS2 = 1;View on GitHub (pinned to 81131a70a4)