spring-projects/spring-framework · error · AmbiguousBindingException
Found candidate reference pointcut variables but only one…
Error message
Found {} candidate reference pointcut variables but only one unbound argument slot What it means
Thrown when one unbound argument slot remains but the pointcut's reference pointcut expressions yield multiple candidate variable names. Spring cannot choose among the candidates for the single slot.
Solutions
- Compile with -parameters to resolve names directly
- Reduce the pointcut to a single reference-pointcut binding or add a parameter for each
- Restructure the pointcut composition to expose only one binding variable
Example fix
// before
@Before("com.x.Pc1.first(p1) && com.x.Pc2.second(p2)")
public void before(Object single) { ... } // 2 candidates, 1 slot
// after
@Before("com.x.Pc1.first(p1)")
public void before(Object p1) { ... } Defensive patterns
Strategy: validation
Validate before calling
// If using reference pointcuts that expose bindings, ensure at most one binding variable per unbound slot // Reference pointcuts are named pointcuts referenced in the expression (not AspectJ keywords). // Compiling with -parameters makes this check unnecessary.
Try / catch
try {
discoverer.getParameterNames(adviceMethod);
} catch (AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException ex) {
// Reduce reference pointcut bindings to one, or add params for each
} Prevention
- Compile with -parameters
- Expose at most one binding variable from reference pointcuts when the advice has a single unbound param
When it happens
Trigger: A pointcut referencing multiple shared named pointcuts that each expose a binding variable, with an advice method that has exactly one unbound slot — e.g. @Before("com.x.Pc1.a(p1) && com.x.Pc2.b(p2)") void before(Object single). Only fires when setRaiseExceptions(true).
Common situations: Composed pointcut references with multiple exposed bindings but a single advice parameter, compiled without -parameters.
Related errors
- Still unbound args at reference pointcut binding stage…
- Binding of returning parameter
- Found candidate annotation binding variables but only one…
- Found candidate this(), target(), or args() variables but…
- Found candidate variable names but only one candidate…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/5b1486a97361f877.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java:577
}
}
// eat the body
PointcutBody body = getPointcutBody(tokens, i);
i += body.numTokensConsumed;
if (!nonReferencePointcutTokens.contains(toMatch)) {
// then it could be a reference pointcut
String varName = maybeExtractVariableName(body.text);
if (varName != null) {
varNames.add(varName);
}
}
}
if (varNames.size() > 1) {
throw new AmbiguousBindingException("Found " + varNames.size() +
" candidate reference pointcut variables but only one unbound argument slot");
}
else if (varNames.size() == 1) {
for (int j = 0; j < this.parameterNameBindings.length; j++) {
if (isUnbound(j)) {
bindParameterName(j, varNames.get(0));
break;
}
}
}
// else varNames.size must be 0 and we have nothing to bind.
}
/**
* We've found the start of a binding pointcut at the given index into the
* token array. Now we need to extract the pointcut body and return it.
*/
private PointcutBody getPointcutBody(String[] tokens, int startIndex) {View on GitHub (pinned to 69bf83ad71)