unoplatform/uno · error · NotSupportedException

The default LookupPositionalParameters implementation does n

Error message

The default LookupPositionalParameters implementation does not allow duplicate arity of markup extensions

What it means

LookupPositionalParameters throws NotSupportedException when a MarkupExtension type has more than one public constructor with the same parameter count (duplicate arity) AND the schema context does not opt into supporting that. Positional markup-extension parameters in XAML (e.g. {Binding path}) map to a specific constructor; if two constructors are ambiguous for a given arity, the default resolver cannot pick one and refuses rather than guess. SupportMarkupExtensionsWithDuplicateArity being false gates whether this throws.

Source

Thrown at src/SourceGenerators/System.Xaml/System.Xaml/XamlType.cs:725

			if (UnderlyingType == null/* || !IsMarkupExtension*/) // see nunit tests...
				return null;

			// check if there is applicable ConstructorArgumentAttribute.
			// If there is, then return its type.
			if (parameterCount == 1) {
				foreach (var xm in GetAllMembers ()) {
					var ca = xm.GetCustomAttributeProvider ().GetCustomAttribute<ConstructorArgumentAttribute> (false);
					if (ca != null)
						return new XamlType [] {xm.Type};
				}
			}

			var methods = (from m in UnderlyingType.GetConstructors (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) where m.GetParameters ().Length == parameterCount select m).ToArray ();
			if (methods.Length == 1)
				return (from p in methods [0].GetParameters () select SchemaContext.GetXamlType (p.ParameterType)).ToArray ();

			if (SchemaContext.SupportMarkupExtensionsWithDuplicateArity)
				throw new NotSupportedException ("The default LookupPositionalParameters implementation does not allow duplicate arity of markup extensions");
			return null;
		}

		BindingFlags flags_get_static = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;

		protected virtual EventHandler<XamlSetMarkupExtensionEventArgs> LookupSetMarkupExtensionHandler ()
		{
			var a = this.GetCustomAttribute<XamlSetMarkupExtensionAttribute> ();
			if (a == null)
				return null;
			var mi = type.GetMethod (a.XamlSetMarkupExtensionHandler, flags_get_static);
			if (mi == null)
				throw new ArgumentException ("Binding to XamlSetMarkupExtensionHandler failed");
			return (EventHandler<XamlSetMarkupExtensionEventArgs>) Delegate.CreateDelegate (typeof (EventHandler<XamlSetMarkupExtensionEventArgs>), mi);
		}

		protected virtual EventHandler<XamlSetTypeConverterEventArgs> LookupSetTypeConverterHandler ()
		{

View on GitHub (pinned to 0418340488)

Solutions

  1. Disambiguate the constructors on the MarkupExtension so each distinct arity has exactly one constructor (remove or rename a colliding overload).
  2. Use named property assignment syntax in XAML ({MyExt Prop=value}) instead of positional arguments, which bypasses positional constructor resolution.
  3. If duplicate arity is intentional, set XamlSchemaContextSettings.SupportMarkupExtensionsWithDuplicateArity = true when constructing the XamlSchemaContext (note: the framework then returns null instead of throwing, pushing resolution elsewhere).

Example fix

// before (MarkupExtension with duplicate arity)
public class MyExt : MarkupExtension {
    public MyExt(string s) {}
    public MyExt(int i) {}
}
// XAML: <Binding Source="{x:Static ...}" /> ambiguous

// after
public class MyExt : MarkupExtension {
    public MyExt(string s) {}
    public string IntValue { get; set; }
}
// XAML: {local:MyExt someText, IntValue=5}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure markup extension has a unique constructor arity:
var arities = typeof(MyExt).GetConstructors().GroupBy(c => c.GetParameters().Length)
    .Where(g => g.Count() > 1).ToArray();
if (arities.Length > 0) throw new InvalidOperationException("Duplicate constructor arity on MyExt");

Try / catch

try { var parms = xamlType.GetPositionalParameters(count); }
catch (NotSupportedException ex) when (ex.Message.Contains("duplicate arity")) {
    // fall back to named-property syntax or report a config error
}

Prevention

When it happens

Trigger: Defining a MarkupExtension subclass with two constructors taking the same number of arguments, then using it with positional arguments in XAML. The resolver finds methods.Length != 1 for the requested parameterCount, and because SupportMarkupExtensionsWithDuplicateArity is false, it throws.

Common situations: Authoring a custom MarkupExtension with overloaded constructors of equal arity; porting WPF markup extensions that rely on a particular overload-resolution rule; third-party extensions that add convenience constructors colliding in arity.

Related errors


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/fec7de7d027483dd. Report an issue: GitHub.