spring-projects/spring-framework · error · IllegalStateException
Required to bind {} arguments, but only bound {} (JoinPointM
Error message
Required to bind {} arguments, but only bound {} (JoinPointMatch {} bound in invocation) What it means
Thrown by argBinding (line 602-606) at advice invocation time when the number of bound arguments (numBound) does not equal the advice method's parameter count. This is a runtime mismatch: the join-point match (jpMatch) did not supply all expected pointcut bindings, or returning/throwing bindings could not be populated.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java:603
}
// binding from returning clause
if (this.returningName != null) {
Integer index = this.argumentBindings.get(this.returningName);
Assert.state(index != null, "Index must not be null");
adviceInvocationArgs[index] = returnValue;
numBound++;
}
// binding from thrown exception
if (this.throwingName != null) {
Integer index = this.argumentBindings.get(this.throwingName);
Assert.state(index != null, "Index must not be null");
adviceInvocationArgs[index] = ex;
numBound++;
}
}
if (numBound != this.parameterTypes.length) {
throw new IllegalStateException("Required to bind " + this.parameterTypes.length +
" arguments, but only bound " + numBound + " (JoinPointMatch " +
(jpMatch == null ? "was NOT" : "WAS") + " bound in invocation)");
}
return adviceInvocationArgs;
}
/**
* Invoke the advice method.
* @param jpMatch the JoinPointMatch that matched this execution join point
* @param returnValue the return value from the method execution (may be null)
* @param ex the exception thrown by the method execution (may be null)
* @return the invocation result
* @throws Throwable in case of invocation failure
*/
protected @Nullable Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable ex) throws Throwable {View on GitHub (pinned to e8729d0438)
Solutions
- Verify the pointcut expression binds exactly the variables the advice method declares (other than join-point/returning/throwing).
- Ensure the JoinPointMatch is stored and retrieved for this advice's expression (ExposeInvocationInterceptor present, same expression key).
- Rebuild proxies after changing the advice signature so bindings are recalculated.
- Simplify the pointcut to deterministically bind all required parameters at every matched join point.
Example fix
// before: pointcut binds 'id' but advice also declares 'name' with no binding source
@After(value = "execution(* svc.*(..)) && args(id,name)")
public void after(Long id, String name) { ... } // matches a method with only one arg
// after
@After(value = "execution(* svc.update(..)) && args(id,name)")
public void after(Long id, String name) { ... } // matches a 2-arg method Defensive patterns
Strategy: validation
Validate before calling
// At setup, verify pointcut-bound parameter names are all produced by the pointcut.
String[] adviceParamNames = new DefaultParameterNameDiscoverer().getParameterNames(adviceMethod);
Set<String> boundByPointcut = pointcutExpressionParameterNames(pointcut.getExpression()); // your extractor
for (String n : requiredBindings(adviceParamNames, returningName, throwingName)) {
if (!boundByPointcut.contains(n)) {
throw new IllegalStateException("Pointcut does not bind parameter '" + n + "' required by " + adviceMethod);
}
} Try / catch
try {
return advice.invokeAdviceMethod(jpMatch, returnValue, ex);
} catch (IllegalStateException ex) {
if (ex.getMessage().startsWith("Required to bind")) {
// log jpMatch null/partial and rethrow with context
throw new IllegalStateException("JoinPointMatch did not supply all bindings for " + adviceMethod, ex);
}
throw ex;
} Prevention
- Ensure the pointcut binds every variable the advice declares (besides join-point/returning/throwing).
- Keep ExposeInvocationInterceptor in the chain so the JoinPointMatch is available at runtime.
- Rebuild proxies after changing advice signatures or pointcuts.
- Avoid pointcuts whose parameter bindings vary across matched join points.
When it happens
Trigger: A pointcut that matched at proxy-creation time but at runtime yields a JoinPointMatch with fewer PointcutParameter bindings than the advice expects (e.g. the pointcut binds variables the advice signature requires, but the runtime match returned null or partial bindings); jpMatch being null when the advice has pointcut-bound parameters.
Common situations: Custom pointcut that inconsistently populates parameter bindings; concurrent/deserialization edge cases losing the JoinPointMatch user attribute; advice parameter list changed after proxy creation; a pointcut expression referencing variables not actually bound at every matched join point.
Related errors
- Mismatch on arguments to advice method [{}]; pointcut expres
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Returning name '{}' is neither a valid argument name nor the
- Throwing name '{}' is neither a valid argument name nor the
- Advice method [{}] requires {} arguments to be bound by name
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/d3eacffee1a45620.json.
Report an issue: GitHub.