spring-projects/spring-framework · error · AmbiguousBindingException

Binding of returning parameter '{}' is ambiguous: there are

Error message

Binding of returning parameter '{}' is ambiguous: there are {} candidates. Consider compiling with -parameters in order to make declared parameter names available.

What it means

Thrown by AspectJAdviceParameterNameDiscoverer when a 'returning' name was specified on an @AfterReturning advice but more than one advice-method parameter remains unbound at the returning-binding stage. Spring cannot decide which of the multiple candidate parameters the return value should bind to, because parameter names were not compiled in (-parameters flag absent). Only surfaces when raiseExceptions=true; otherwise the discoverer returns null and the failure is logged.

Source

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

					"' could not be completed as no available arguments are a subtype of Throwable");
		}
		else {
			bindParameterName(throwableIndex, this.throwingName);
		}
	}

	/**
	 * If a returning variable was specified and there is only one choice remaining, bind it.
	 */
	private void maybeBindReturningVariable() {
		if (this.numberOfRemainingUnboundArguments == 0) {
			throw new IllegalStateException(
					"Algorithm assumes that there must be at least one unbound parameter on entry to this method");
		}

		if (this.returningName != null) {
			if (this.numberOfRemainingUnboundArguments > 1) {
				throw new AmbiguousBindingException("Binding of returning parameter '" + this.returningName +
						"' is ambiguous: there are " + this.numberOfRemainingUnboundArguments + " candidates. " +
						"Consider compiling with -parameters in order to make declared parameter names available.");
			}

			// We're all set... find the unbound parameter, and bind it.
			for (int i = 0; i < this.parameterNameBindings.length; i++) {
				if (this.parameterNameBindings[i] == null) {
					bindParameterName(i, this.returningName);
					break;
				}
			}
		}
	}

	/**
	 * Parse the string pointcut expression looking for:
	 * &#64;this, &#64;target, &#64;args, &#64;within, &#64;withincode, &#64;annotation.
	 * If we find one of these pointcut expressions, try and extract a candidate variable

View on GitHub (pinned to e8729d0438)

Solutions

  1. Compile with javac -parameters (or <parameters>true</parameters> in maven-compiler-plugin / compilerArgs in Gradle) so real parameter names are available.
  2. Reduce the advice method to exactly one unbound parameter at the returning stage by adding explicit pointcut binding (this/target/args/annotation) for the other parameters.
  3. Remove the extra parameters from the advice signature that are not actually needed.
  4. If using @AfterReturning, ensure the returning attribute type matches exactly one parameter.

Example fix

// before
@AfterReturning(pointcut="execution(* com.acme.*.*(..))", returning="ret")
public void after(Object ret, Object extra) { ... }

// after
@AfterReturning(pointcut="execution(* com.acme.*.*(..))", returning="ret")
public void after(Object ret) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Compile with -parameters; verify before deploying:
// javac -parameters ...
// or in advice, keep exactly one unbound param at the returning stage.

Prevention

When it happens

Trigger: An @AfterReturning advice method with multiple untyped/unbound parameters (e.g. two Objects) combined with returning="someName", where the pointcut expression and prior binding stages (JoinPoint, throwing, annotation) did not resolve enough parameters to leave exactly one unbound slot.

Common situations: Advice methods written with several parameters that are not named in bytecode; migrating from ajc-compiled aspects (which embed parameter names) to javac-compiled ones; upgrading Spring versions where stricter binding checks were added.

Related errors


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