spring-projects/spring-framework · error · IllegalStateException
Failed to bind all argument names
Error message
Failed to bind all argument names: {} argument(s) could not be bound What it means
Thrown by AspectJAdviceParameterNameDiscoverer.getParameterNames (line 270-273) after the full 7-step binding algorithm (join point, throwing, annotation, returning, primitive args, this/target/args, reference pointcut) has run and numberOfRemainingUnboundArguments is still > 0. Every heuristic was exhausted and some parameters could not be assigned a name, so binding cannot complete. Only raised when raiseExceptions is true (which AbstractAspectJAdvice sets at line 461).
Solutions
- Compile with -parameters so DefaultParameterNameDiscoverer can supply names before this discoverer runs.
- Add a binding form to the pointcut (args(x), this(x), target(x), @annotation(x)) for each remaining parameter.
- Explicitly specify arg-names so the discoverer is bypassed.
- Remove parameters the pointcut cannot bind.
Example fix
// before — pointcut binds nothing, advice has an unbindable param, no -parameters
@After("execution(* svc.*(..))")
public void after(JoinPoint jp, Object mystery) { ... }
// after — bind 'mystery' via args() or name it explicitly
@After("execution(* svc.*(..)) && args(mystery)")
public void after(JoinPoint jp, Object mystery) { ... } Defensive patterns
Strategy: validation
Validate before calling
import org.springframework.core.DefaultParameterNameDiscoverer;
import java.lang.reflect.Method;
// Pre-flight: confirm parameter names are discoverable OR pointcut binds all params.
boolean bindingWillSucceed(Method adviceMethod, String pointcutExpr) {
String[] names = new DefaultParameterNameDiscoverer().getParameterNames(adviceMethod);
return names != null; // simplest reliable pre-check; else ensure pointcut binds everything
} Type guard
boolean namesAvailableOrFullyBound(Method m, String pointcutExpr) {
return new org.springframework.core.DefaultParameterNameDiscoverer().getParameterNames(m) != null
|| pointcutExpr.matches(".*(args|this|target|@annotation|@args)\\(.*\\).*");
} Try / catch
try {
advice.getPointcut();
} catch (IllegalStateException ex) {
if (ex.getMessage().contains("could not be bound")) {
// add a binding form to the pointcut or compile with -parameters, then retry
} else { throw ex; }
} Prevention
- Compile with -parameters so names are always available.
- Add a binding form (args/this/target/@annotation) for every non-joinpoint parameter.
- Supply arg-names explicitly when in doubt.
When it happens
Trigger: An advice method has a parameter that none of the heuristics can name: it is not a JoinPoint/StaticPart, not a Throwable (when throwing set), not an Annotation (when @annotation set), not a primitive (when args() set), and not matchable via this()/target()/args()/reference pointcut. Typically a method with an extra parameter that the pointcut expression does not account for.
Common situations: Adding a parameter to an advice method that the pointcut does not bind, compiling without -parameters so names are unavailable, or using a pointcut expression with no bindable forms. Common when migrating from annotation-driven binding to pure pointcut-string binding.
Related errors
- Advice method [ ] requires arguments to be bound by name…
- Binding of throwing parameter
- Not enough arguments in method to satisfy binding of…
- An advice method can never be a constructor
- 'argumentNames' property of AbstractAspectJAdvice contains…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/cc035866de8e80ed.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java:271
default -> throw new IllegalStateException("Unknown algorithmic step: " + (algorithmicStep - 1));
}
}
}
catch (AmbiguousBindingException | IllegalArgumentException ex) {
if (this.raiseExceptions) {
throw ex;
}
else {
return null;
}
}
if (this.numberOfRemainingUnboundArguments == 0) {
return this.parameterNameBindings;
}
else {
if (this.raiseExceptions) {
throw new IllegalStateException("Failed to bind all argument names: " +
this.numberOfRemainingUnboundArguments + " argument(s) could not be bound");
}
else {
// convention for failing is to return null, allowing participation in a chain of responsibility
return null;
}
}
}
/**
* An advice method can never be a constructor in Spring.
* @return {@code null}
* @throws UnsupportedOperationException if
* {@link #setRaiseExceptions(boolean) raiseExceptions} has been set to {@code true}
*/
@Override
public String @Nullable [] getParameterNames(Constructor<?> ctor) {
if (this.raiseExceptions) {View on GitHub (pinned to 69bf83ad71)