dotnet/wpf · error · ArgumentException

SR.ParserAttributeArgsLow with…

Error message

SR.ParserAttributeArgsLow with 'XmlnsCompatibleWithAttribute' (missing XmlnsCompatibleWithAttribute constructor arguments)

What it means

XmlnsCache throws ArgumentException when an [XmlnsCompatibleWithAttribute] found in a scanned assembly yields an empty OldNamespace or NewNamespace. The attribute requires both constructor arguments to be non-empty namespace strings, so a malformed usage in a referenced assembly makes the WPF XAML markup cache unable to build a valid compatibility mapping.

Solutions

  1. Open the referenced assembly's source and provide both non-empty arguments to XmlnsCompatibleWithAttribute: [assembly: XmlnsCompatibleWith("old-clr-ns", "new-clr-ns")]
  2. Identify the offending assembly by scanning referenced assemblies for XmlnsCompatibleWithAttribute usage and inspecting its OldNamespace/NewNamespace values
  3. Remove the invalid XmlnsCompatibleWithAttribute entirely if the namespace compatibility mapping is not needed
  4. Rebuild/reinstall the third-party assembly from a correct source version

Example fix

// before (AssemblyInfo.cs of referenced assembly)
[assembly: XmlnsCompatibleWith("")] // missing args

// after
[assembly: XmlnsCompatibleWith("clr-namespace:Old.Ns", "clr-namespace:New.Ns")]
Defensive patterns

Strategy: validation

Validate before calling

var attr = asm.GetCustomAttribute<XmlnsCompatibleWithAttribute>();
if (attr != null && (string.IsNullOrEmpty(attr.OldNamespace) || string.IsNullOrEmpty(attr.NewNamespace)))
    throw new InvalidOperationException($"Assembly {asm.GetName().Name} has an XmlnsCompatibleWithAttribute with empty namespace arguments.");

Prevention

When it happens

Trigger: Calling AddReferencedAssemblies or GetMappingArray while scanning an assembly whose [assembly: XmlnsCompatibleWith(...)] attribute was declared with null/empty string arguments (e.g. XmlnsCompatibleWith("", "newNs") or omitted constructor args).

Common situations: Hand-edited AssemblyInfo.cs, misapplied attribute via reflection-emitted assemblies, or a third-party WPF assembly with a corrupt/incorrect XmlnsCompatibleWithAttribute declaration discovered when the XAML designer or markup compiler builds the xmlns compatibility table.

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


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/092ecb92c2dfbfce. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XmlnsCache.cs:387

            {
#if PBTCOMPILER
                CustomAttributeData[] attributes = GetAttributes(asmList[asmIdx],
                                                "System.Windows.Markup.XmlnsCompatibleWithAttribute");
#else
                Attribute[] attributes = GetAttributes(asmList[asmIdx],
                                                typeof(XmlnsCompatibleWithAttribute));
#endif

                for(int attrIdx=0; attrIdx<attributes.Length; attrIdx++)
                {
                    string oldXmlns = null;
                    string newXmlns = null;

                    GetNamespacesFromCompatAttr(attributes[attrIdx], out oldXmlns, out newXmlns);

                    if (String.IsNullOrEmpty(oldXmlns) || String.IsNullOrEmpty(newXmlns))
                    {
                        throw new ArgumentException(SR.Format(SR.ParserAttributeArgsLow, "XmlnsCompatibleWithAttribute"));
                    }

                    if (_compatTable.ContainsKey(oldXmlns) &&
                        _compatTable[oldXmlns] != newXmlns)
                    {
                        throw new InvalidOperationException(SR.Format(SR.ParserCompatDuplicate, oldXmlns,
                                                                   _compatTable[oldXmlns]));
                    }
                    _compatTable[oldXmlns] = newXmlns;
                    _compatTableReverse[newXmlns] = oldXmlns;
                }
            }
        }

        // Table where Xml namespace is the key, and value is a list of assembly / clrns pairs
        private HybridDictionary _cacheTable = null;

        // Table where old namespaces are the key, and new namespaces are the value

View on GitHub (pinned to 81131a70a4)