dotnet/wpf · error · XamlSchemaException

XamlSchemaException(SR.Format(SR.MarkupExtensionWithDuplicat…

Error message

XamlSchemaException(SR.Format(SR.MarkupExtensionWithDuplicateArity, UnderlyingType, typeVector.Length))

What it means

When computing constructor-based lookup for a markup extension type, XAML allows at most one constructor per arity unless the schema context enables SupportMarkupExtensionsWithDuplicateArity. If two usable constructors share the same parameter count and the feature is disabled, XamlSchemaException MarkupExtensionWithDuplicateArity is thrown.

Solutions

  1. Remove or consolidate constructors so each arity appears at most once (e.g. chain one ctor to another with defaults)
  2. Enable duplicate arity on the schema context: new XamlSchemaContext(null, new XamlSchemaContextSettings { SupportMarkupExtensionsWithDuplicateArity = true })
  3. Mark the less-specific constructor non-public or add a distinguishing parameter

Example fix

// before
public MyExtension(string s) { ... }
public MyExtension(Type t) { ... }  // duplicate arity 1
// after
public MyExtension(string s) { ... }
public MyExtension(Type t, int extra) { ... }  // distinct arities
// or: new XamlSchemaContext(null, new XamlSchemaContextSettings { SupportMarkupExtensionsWithDuplicateArity = true })
Defensive patterns

Strategy: try-catch

Validate before calling

var ctorArities = typeof(MyExtension).GetConstructors().Select(c => c.GetParameters().Length);
bool hasDuplicateArity = ctorArities.GroupBy(a => a).Any(g => g.Count() > 1);

Try / catch

try { var t = schemaContext.GetXamlType(meType); }
catch (XamlSchemaException ex) when (ex.Message.Contains("arity")) { /* enable duplicate arity or fix ctors */ }

Prevention

When it happens

Trigger: Using a markup extension class that defines two constructors with the same number of parameters (e.g. ctor(string) and ctor(Type)) in XAML markup extension resolution, while the XamlSchemaContext has SupportMarkupExtensionsWithDuplicateArity == false (the default).

Common situations: Custom markup extensions with convenience overloads used inside XAML; moving markup extensions from environments where duplicate arity was enabled to default contexts; adding an overload to an existing extension that previously had unique arities.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlType.cs:1711

            Dictionary<int, IList<XamlType>> ctorDict = new Dictionary<int, IList<XamlType>>();
            foreach (ConstructorInfo info in GetConstructors())
            {
                ParameterInfo[] parameterInfos = info.GetParameters();
                XamlType[] typeVector = new XamlType[parameterInfos.Length];
                for (int i = 0; i < parameterInfos.Length; i++)
                {
                    ParameterInfo param = parameterInfos[i];
                    Type type = param.ParameterType;
                    XamlType xamlType = SchemaContext.GetXamlType(type);
                    typeVector[i] = xamlType;
                }

                if (ctorDict.ContainsKey(typeVector.Length))
                {
                    if (!SchemaContext.SupportMarkupExtensionsWithDuplicateArity)
                    {
                        throw new XamlSchemaException(SR.Format(SR.MarkupExtensionWithDuplicateArity, UnderlyingType, typeVector.Length));
                    }

                    // Otherwise we just ignore the dupe
                }
                else
                {
                    ctorDict.Add(typeVector.Length, GetReadOnly(typeVector));
                }
            }

            return ctorDict;
        }

        private bool LookupBooleanValue(BoolTypeBits typeBit)
        {
            bool bit;
            switch (typeBit)
            {

View on GitHub (pinned to 81131a70a4)