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

  1. Verify the pointcut expression binds exactly the variables the advice method declares (other than join-point/returning/throwing).
  2. Ensure the JoinPointMatch is stored and retrieved for this advice's expression (ExposeInvocationInterceptor present, same expression key).
  3. Rebuild proxies after changing the advice signature so bindings are recalculated.
  4. 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

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


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/d3eacffee1a45620.json. Report an issue: GitHub.