dotnet/wpf · error · AmbiguousMatchException
throw new AmbiguousMatchException();
Error message
throw new AmbiguousMatchException();
What it means
AttachedPropertyMethodSelector.SelectMethod (a Binder override used by WPF's attached-property method resolution) throws AmbiguousMatchException when no types array is supplied and more than one candidate MethodInfo matches. Without type information it cannot disambiguate between overloads.
Solutions
- Provide a types array so overload resolution can disambiguate the candidates
- Rename or remove the duplicate overloads so only one method matches the attached-property naming convention
- Ensure attached property accessor signatures follow the exact expected pattern (single DependencyObject parameter for getters)
- Catch AmbiguousMatchException at the resolution site and apply a tie-breaking rule
Example fix
// before
binder.SelectMethod(bindingAttr, match, null, modifiers);
// after
binder.SelectMethod(bindingAttr, match, new Type[] { typeof(DependencyObject) }, modifiers); Defensive patterns
Strategy: validation
Validate before calling
if (match == null) throw new ArgumentNullException(nameof(match));
if (types == null && match.Length > 1)
throw new AmbiguousMatchException("Multiple overloads; provide types array"); Type guard
bool UnambiguousWithoutTypes(MethodBase[] m) => m != null && (m.Length == 1 || m.Select(x => x.GetParameters().Length).Distinct().Count() == 1);
Try / catch
try { var mi = binder.SelectMethod(bindingAttr, match, types, modifiers); }
catch (AmbiguousMatchException) { mi = match.FirstOrDefault(x => x.GetParameters().Length == 1); } Prevention
- Always supply a types array when resolving possibly-overloaded methods
- Follow the standard attached-property accessor signature (Get*/Set* with DependencyObject first param)
- Avoid declaring multiple overloads for attached property accessors
When it happens
Trigger: Resolving an attached property getter/setter method where multiple overloads match the method name and the caller passed types == null to SelectMethod.
Common situations: XAML/attached-property processing selecting methods like GetFoo/SetFoo that have overloads; reflection-based property engine lookups without explicit parameter types.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- throw new NotImplementedException();
- Event not found: Event 'eventName' not found on type…
- NotImplementedException
- SR.BamlReaderNoOwnerType
- SR.CollectionView_ViewTypeInsufficient
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b14acb8f8da43e65.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/ComponentModel/AttachedPropertyMethodSelector.cs:33
/// matching to find a match for any parameters that are
/// compatible.
/// </summary>
internal class AttachedPropertyMethodSelector : Binder
{
/// <summary>
/// The only method we implement. Our goal here is to find a method that best matches the arguments passed.
/// We are doing this only with the intent of pulling attached property metadata off of the method.
/// If there are ambiguous methods, we simply take the first one as all "Get" methods for an attached
/// property should have identical metadata.
/// </summary>
public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
{
// Short circuit for cases where someone didn't pass in a types array.
if (types == null)
{
if (match.Length > 1)
{
throw new AmbiguousMatchException();
}
else
{
return match[0];
}
}
for(int idx = 0; idx < match.Length; idx++)
{
MethodBase candidate = match[idx];
ParameterInfo[] parameters = candidate.GetParameters();
if (ParametersMatch(parameters, types))
{
return candidate;
}
}
return null;View on GitHub (pinned to 81131a70a4)