spring-projects/spring-framework · error · IllegalStateException

Failed to bind all argument names: {} argument(s) could not

Error message

Failed to bind all argument names: {} argument(s) could not be bound

What it means

Thrown by AspectJAdviceParameterNameDiscoverer.getParameterNames (line 270-273) when raiseExceptions is true and after running the full binding algorithm some parameters remain unbound. This is a catch-all failure: the heuristic chain (join-point, throwing, annotation, returning, primitive, this/target/args, reference pointcut) could not account for every parameter.

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 e8729d0438)

Solutions

  1. Provide explicit arg-names matching every parameter so discovery is not needed.
  2. Compile with -parameters so reflection-based discovery (DefaultParameterNameDiscoverer) can supply names earlier in the chain.
  3. Ensure every non-join-point parameter has a corresponding binding form in the pointcut (args/this/target/@annotation) or is a returning/throwing param.
  4. Remove surplus parameters from the advice method.

Example fix

// before: extra 'ctx' param has no binding source
@After(value = "execution(* svc.*(..)) && args(id)")
public void after(Long id, String ctx) { ... }
// after
@After(value = "execution(* svc.*(..)) && args(id,ctx)")
public void after(Long id, String ctx) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on discovery, ensure every non-join-point param has a binding source.
int jpOffset = (firstParamIsJoinPointLike(adviceMethod) ? 1 : 0);
int bindableFromExpr = countBindingForms(pointcutExpression); // args/this/target/@annotation etc.
int returningThrowing = (returningName != null ? 1 : 0) + (throwingName != null ? 1 : 0);
int needed = adviceMethod.getParameterCount() - jpOffset - returningThrowing;
if (bindableFromExpr < needed) {
    throw new IllegalStateException("Pointcut binds " + bindableFromExpr
        + " but advice needs " + needed + " named parameters; add arg-names or fix the pointcut");
}

Prevention

When it happens

Trigger: An advice method has parameters that none of the binding heuristics can match to the pointcut expression: extra parameters with no corresponding pointcut binding form; complex pointcuts with multiple ambiguous candidates; parameters whose names can't be discovered and aren't implied by the expression.

Common situations: Advice method declares more parameters than the pointcut binds; pointcut uses binding forms the heuristic doesn't recognize; raising exceptions is enabled (the discoverer is last in the chain) and a genuinely unresolvable parameter exists; relying on discovery instead of explicit arg-names.

Related errors


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