spring-projects/spring-framework · error · UnsupportedOperationException
Only afterReturning advice can be used to bind a return valu
Error message
Only afterReturning advice can be used to bind a return value
What it means
The base AbstractAspectJAdvice.setReturningName(String) (line 291-293) is intentionally a guard: it throws UnsupportedOperationException because only after-returning advice semantics can bind a return value. The concrete AspectJAfterReturningAdvice overrides this method; calling it on any other advice subtype (before, after, after-throwing, around) hits this guard.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java:292
// May need to add implicit join point arg name...
for (int i = 0; i < this.aspectJAdviceMethod.getParameterCount(); i++) {
Class<?> argType = this.aspectJAdviceMethod.getParameterTypes()[i];
if (argType == JoinPoint.class ||
argType == ProceedingJoinPoint.class ||
argType == JoinPoint.StaticPart.class) {
@Nullable String[] oldNames = this.argumentNames;
this.argumentNames = new String[oldNames.length + 1];
System.arraycopy(oldNames, 0, this.argumentNames, 0, i);
this.argumentNames[i] = "THIS_JOIN_POINT";
System.arraycopy(oldNames, i, this.argumentNames, i + 1, oldNames.length - i);
break;
}
}
}
}
public void setReturningName(String name) {
throw new UnsupportedOperationException("Only afterReturning advice can be used to bind a return value");
}
/**
* We need to hold the returning name at this level for argument binding calculations,
* this method allows the afterReturning advice subclass to set the name.
*/
protected void setReturningNameNoCheck(String name) {
// name could be a variable or a type...
if (isVariableName(name)) {
this.returningName = name;
}
else {
// assume a type
try {
this.discoveredReturningType = ClassUtils.forName(name, getAspectClassLoader());
}
catch (Throwable ex) {
throw new IllegalArgumentException("Returning name '" + name +View on GitHub (pinned to e8729d0438)
Solutions
- Move the 'returning' attribute onto an <aop:after-returning> element (or @AfterReturning advice) only.
- Remove the 'returning' attribute from the before/after/after-throwing/around element causing the error.
- If binding a return value is genuinely needed, switch that advice to after-returning semantics.
- When building advice programmatically, only call setReturningName on an AspectJAfterReturningAdvice instance.
Example fix
// before <aop:aspect ref="audit"> <aop:after-throwing method="onEx" pointcut="..." returning="ret"/> </aop:aspect> // after <aop:aspect ref="audit"> <aop:after-returning method="onRet" pointcut="..." returning="ret"/> </aop:aspect>
Defensive patterns
Strategy: validation
Validate before calling
// Only call setReturningName on the correct advice subtype.
if (advice instanceof AspectJAfterReturningAdvice) {
advice.setReturningName(name);
} else {
throw new IllegalStateException("returning binding requires after-returning advice, got " + advice.getClass());
} Type guard
private static boolean supportsReturning(AbstractAspectJAdvice a) {
return a instanceof AspectJAfterReturningAdvice;
} Try / catch
try {
advice.setReturningName(name);
} catch (UnsupportedOperationException ex) {
throw new IllegalStateException(
"'returning' is only valid on after-returning advice; remove it from " + advice.getClass().getSimpleName(), ex);
} Prevention
- Place 'returning' only on after-returning advice (XML element or @AfterReturning).
- When templating advice XML, change the advice kind and remove returning/throwing together.
- Programmatic advice construction: branch on advice type before setting returning/throwing.
When it happens
Trigger: Invoking setReturningName on an AspectJMethodBeforeAdvice, AspectJAfterAdvice, AspectJAfterThrowingAdvice, or AspectJAroundAdvice instance, or configuring a 'returning' attribute on an <aop:before>, <aop:after>, <aop:after-throwing>, or <aop:around> element.
Common situations: XML misconfiguration: putting returning="ret" on the wrong advice element; copy-pasting an after-returning block and changing the advice kind without removing 'returning'; programmatically building advice objects and generically calling setReturningName.
Related errors
- Only afterThrowing advice can be used to bind a thrown excep
- Returning argument name '{}' was not bound in advice argumen
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Returning name '{}' is neither a valid argument name nor the
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/af7ae38958aef30f.json.
Report an issue: GitHub.