spring-projects/spring-framework · error · AmbiguousBindingException

Still {} unbound args at reference pointcut binding stage, w

Error message

Still {} unbound args at reference pointcut binding stage, with no way to determine between them

What it means

Thrown at the reference-pointcut binding stage when more than one parameter is still unbound. A reference pointcut (a named pointcut referenced by name) can supply at most one binding variable, so multiple unbound slots make binding impossible. Only surfaces when raiseExceptions=true.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java:533

		if (varNames.size() > 1) {
			throw new AmbiguousBindingException("Found " + varNames.size() +
					" candidate this(), target(), or args() variables but only one unbound argument slot");
		}
		else if (varNames.size() == 1) {
			for (int j = 0; j < this.parameterNameBindings.length; j++) {
				if (isUnbound(j)) {
					bindParameterName(j, varNames.get(0));
					break;
				}
			}
		}
		// else varNames.size must be 0 and we have nothing to bind.
	}

	private void maybeBindReferencePointcutParameter() {
		if (this.numberOfRemainingUnboundArguments > 1) {
			throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments +
					" unbound args at reference pointcut binding stage, with no way to determine between them");
		}

		List<String> varNames = new ArrayList<>();
		String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
		for (int i = 0; i < tokens.length; i++) {
			String toMatch = tokens[i];
			if (toMatch.startsWith("!")) {
				toMatch = toMatch.substring(1);
			}
			int firstParenIndex = toMatch.indexOf('(');
			if (firstParenIndex != -1) {
				toMatch = toMatch.substring(0, firstParenIndex);
			}
			else {
				if (tokens.length < i + 2) {
					// no "(" and nothing following
					continue;

View on GitHub (pinned to e8729d0438)

Solutions

  1. Compile with -parameters so earlier stages resolve parameters and fewer reach this stage.
  2. Bind remaining parameters via returning/throwing/annotation/args so at most one is left.
  3. Reduce the advice method parameter count.

Example fix

// before
@Pointcut("execution(* com.acme.*.*(..))")
public void pc() {}
@Before("pc() && args(val)")
public void before(Object val, Object extra) { ... }

// after
@Before("pc() && args(val)")
public void before(Object val) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure at most one unbound param when relying on reference pointcut binding; else compile -parameters.

Prevention

When it happens

Trigger: An advice method with two or more unbound parameters reaches the final reference-pointcut binding stage, and the referenced pointcut body yields a candidate variable name.

Common situations: Complex pointcut compositions referencing named pointcuts with multiple unbound advice parameters; missing -parameters flag.

Related errors


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