spring-projects/spring-framework · error · IllegalStateException

Advice method [{}] requires {} arguments to be bound by name

Error message

Advice method [{}] requires {} arguments to be bound by name, but the argument names were not specified and could not be discovered.

What it means

Thrown by bindArgumentsByName (line 432-445) when the advice method has parameters requiring name-based binding but argumentNames is null and the ParameterNameDiscoverer chain (including AspectJAdviceParameterNameDiscoverer) could not discover them. Spring cannot map pointcut bindings to advice parameters without names.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java:441

		if (JoinPoint.StaticPart.class == candidateParameterType) {
			this.joinPointStaticPartArgumentIndex = 0;
			return true;
		}
		else {
			return false;
		}
	}

	private void bindArgumentsByName(int numArgumentsExpectingToBind) {
		if (this.argumentNames == null) {
			this.argumentNames = createParameterNameDiscoverer().getParameterNames(this.aspectJAdviceMethod);
		}
		if (this.argumentNames != null) {
			// We have been able to determine the arg names.
			bindExplicitArguments(numArgumentsExpectingToBind);
		}
		else {
			throw new IllegalStateException("Advice method [" + this.aspectJAdviceMethod.getName() + "] " +
					"requires " + numArgumentsExpectingToBind + " arguments to be bound by name, but " +
					"the argument names were not specified and could not be discovered.");
		}
	}

	/**
	 * Create a ParameterNameDiscoverer to be used for argument binding.
	 * <p>The default implementation creates a {@link DefaultParameterNameDiscoverer}
	 * and adds a specifically configured {@link AspectJAdviceParameterNameDiscoverer}.
	 */
	protected ParameterNameDiscoverer createParameterNameDiscoverer() {
		// We need to discover them, or if that fails, guess,
		// and if we can't guess with 100% accuracy, fail.
		DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
		AspectJAdviceParameterNameDiscoverer adviceParameterNameDiscoverer =
				new AspectJAdviceParameterNameDiscoverer(this.pointcut.getExpression());
		adviceParameterNameDiscoverer.setReturningName(this.returningName);
		adviceParameterNameDiscoverer.setThrowingName(this.throwingName);

View on GitHub (pinned to e8729d0438)

Solutions

  1. Compile with -parameters (javac / Maven compiler-plugin / Gradle '--parameters') so reflection can read parameter names.
  2. Add an explicit 'arg-names' attribute (XML) or 'argNames' in the annotation listing each advice parameter name.
  3. Simplify the pointcut so the binding is unambiguous (single unbound arg, clear args()/this()/target() binding form).
  4. Annotate parameter names via a discoverer that supplies them, or refactor the advice to take a JoinPoint plus fewer bound params.

Example fix

// before
@AfterReturning(value = "args(req)", returning = "ret")
public void log(Object req, Object ret) { ... } // compiled without -parameters
// after (option A)
@AfterReturning(value = "args(req)", returning = "ret", argNames = "req,ret")
public void log(Object req, Object ret) { ... }
// after (option B) compile with -parameters
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on discovery, confirm parameter names are obtainable.
ParameterNameDiscoverer d = new DefaultParameterNameDiscoverer();
String[] names = d.getParameterNames(adviceMethod);
if (names == null && adviceMethod.getParameterCount() > 0) {
    throw new IllegalStateException(
        "Parameter names unavailable for " + adviceMethod + " — compile with -parameters or supply arg-names");
}

Prevention

When it happens

Trigger: An advice method with one or more parameters that must be bound from the pointcut (e.g. args(x)) where: arg-names is not provided, the class was compiled without -parameters (so reflection can't read names), and the AspectJAdviceParameterNameDiscoverer could not deduce them unambiguously from the pointcut expression.

Common situations: Building/running without the -parameters javac flag; obfuscated/stripped bytecode; complex pointcuts the heuristic discoverer cannot resolve (multiple unbound args, no this/target/args binding form); advice methods whose param names were never compiled in.

Related errors


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