spring-projects/spring-framework · error · AopInvocationException
Mismatch on arguments to advice method
Error message
Mismatch on arguments to advice method [{}]; pointcut expression [{}] What it means
Thrown by invokeAdviceMethodWithGivenArgs (line 650-654) as an AopInvocationException wrapping an IllegalArgumentException from Method.invoke. The underlying cause is that the assembled argument array does not match the advice method's formal parameters at reflective invocation time (wrong count or incompatible types). The message includes both the advice method and the pointcut expression to aid diagnosis.
Solutions
- Inspect the wrapped IllegalArgumentException cause to see which argument failed type conversion.
- Make the advice parameter type a supertype of the bound value (e.g. Object instead of a narrow type).
- For returning, use a type restriction that matches the actual return type, or widen the parameter.
- Verify args()/this()/target() bindings correspond in type and order to the advice parameters.
Example fix
// before — parameter type narrower than bound value
@AfterReturning(pointcut="execution(* svc.*(..))", returning="r")
public void after(String r) { ... } // but target returns Integer -> ClassCastException at invoke
// after — widen the parameter type
@AfterReturning(pointcut="execution(* svc.*(..))", returning="r")
public void after(Object r) { ... } Defensive patterns
Strategy: try-catch
Validate before calling
import java.lang.reflect.Method;
// Pre-check assignable types between bound values and advice params (best-effort for returning).
void assertReturningTypeCompatible(Method adviceMethod, String returningName, Class<?> returnType) {
String[] names = new org.springframework.core.DefaultParameterNameDiscoverer().getParameterNames(adviceMethod);
Class<?>[] types = adviceMethod.getParameterTypes();
for (int i = 0; names != null && i < names.length; i++) {
if (names[i].equals(returningName) && !types[i].isAssignableFrom(returnType)) {
throw new IllegalStateException("returning param type " + types[i] + " cannot accept " + returnType);
}
}
} Type guard
boolean returningTypeAccepts(Method m, String returningName, Class<?> returnType) {
String[] names = new org.springframework.core.DefaultParameterNameDiscoverer().getParameterNames(m);
Class<?>[] types = m.getParameterTypes();
for (int i = 0; names != null && i < names.length; i++) {
if (names[i].equals(returningName)) return types[i].isAssignableFrom(returnType);
}
return false;
} Try / catch
import org.springframework.aop.AopInvocationException;
try {
proxy.businessMethod();
} catch (AopInvocationException ex) {
// ex.getMessage() contains the advice method + pointcut expression;
// cause is IllegalArgumentException naming the offending argument
Throwable cause = ex.getCause();
// widen the parameter type or fix the binding, then retry
} Prevention
- Use widening parameter types (Object) for returning/args bindings to avoid ClassCastException at invoke.
- Keep the pointcut binding variable types aligned with advice parameter types.
- Cover advice paths with integration tests invoking the real proxy.
When it happens
Trigger: The bound argument values (from pointcut match + returning + throwing) have types incompatible with the advice method's declared parameter types — e.g. an args() binding yields a String but the parameter is Integer, or returning binds a value whose runtime type is not assignable to the declared parameter type. Distinct from error [11] (which is about count); this is about the reflective invoke failing.
Common situations: Pointcut binds a variable whose runtime type does not match the advice parameter type, the returning type restriction is looser than the parameter, or a generic/erasure mismatch. Common after changing a target method's signature so the bound value's type changes, or after a refactoring that alters which value an args() variable captures.
Related errors
- Required to bind arguments, but only bound (JoinPointMatch…
- Advice method [ ] requires arguments to be bound by name…
- 'argumentNames' property of AbstractAspectJAdvice contains…
- Binding of throwing parameter
- Expecting to find arguments to bind by name in advice, but…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/a62a53792e0673d1.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java:651
protected @Nullable Object invokeAdviceMethodWithGivenArgs(@Nullable Object[] args) throws Throwable {
@Nullable Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
Object aspectInstance = this.aspectInstanceFactory.getAspectInstance();
if (aspectInstance.equals(null)) {
// Possibly a NullBean -> simply proceed if necessary.
if (getJoinPoint() instanceof ProceedingJoinPoint pjp) {
return pjp.proceed();
}
return null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
return this.aspectJAdviceMethod.invoke(aspectInstance, actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
/**
* Overridden in around advice to return proceeding join point.
*/
protected JoinPoint getJoinPoint() {
return currentJoinPoint();
}
/**
* Get the current join point match at the join point we are being dispatched on.
*/View on GitHub (pinned to 69bf83ad71)