spring-projects/spring-framework · error · AopConfigException
Invalid afterThrowing signature: single argument must be a T
Error message
Invalid afterThrowing signature: single argument must be a Throwable subclass
What it means
ThrowsAdviceInterceptor scans public methods named 'afterThrowing' on the advice object. The single-argument variant must take a Throwable subclass. If the lone parameter is not assignable to Throwable, AopConfigException is thrown because the handler could never receive an exception.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/framework/adapter/ThrowsAdviceInterceptor.java:88
/**
* Create a new ThrowsAdviceInterceptor for the given ThrowsAdvice.
* @param throwsAdvice the advice object that defines the exception handler methods
* (usually a {@link org.springframework.aop.ThrowsAdvice} implementation)
*/
public ThrowsAdviceInterceptor(Object throwsAdvice) {
Assert.notNull(throwsAdvice, "Advice must not be null");
this.throwsAdvice = throwsAdvice;
Method[] methods = throwsAdvice.getClass().getMethods();
for (Method method : methods) {
if (method.getName().equals(AFTER_THROWING)) {
Class<?> throwableParam = null;
if (method.getParameterCount() == 1) {
// just a Throwable parameter
throwableParam = method.getParameterTypes()[0];
if (!Throwable.class.isAssignableFrom(throwableParam)) {
throw new AopConfigException("Invalid afterThrowing signature: " +
"single argument must be a Throwable subclass");
}
}
else if (method.getParameterCount() == 4) {
// Method, Object[], target, throwable
Class<?>[] paramTypes = method.getParameterTypes();
if (!Method.class.equals(paramTypes[0]) || !Object[].class.equals(paramTypes[1]) ||
Throwable.class.equals(paramTypes[2]) || !Throwable.class.isAssignableFrom(paramTypes[3])) {
throw new AopConfigException("Invalid afterThrowing signature: " +
"four arguments must be Method, Object[], target, throwable: " + method);
}
throwableParam = paramTypes[3];
}
if (throwableParam == null) {
throw new AopConfigException("Unsupported afterThrowing signature: single throwable argument " +
"or four arguments Method, Object[], target, throwable expected: " + method);
}
// An exception handler to register...View on GitHub (pinned to e8729d0438)
Solutions
- Change the single-parameter afterThrowing method to take a Throwable (or a subclass like Exception).
- If you intended a 4-arg handler, use the full signature: Method, Object[], Object, Throwable.
- Remove the invalid overload so only compliant signatures remain.
Example fix
// before
public void afterThrowing(String msg) { ... }
// after
public void afterThrowing(Exception ex) { ... } Defensive patterns
Strategy: validation
Validate before calling
for (Method m : advice.getClass().getMethods()) {
if (m.getName().equals("afterThrowing") && m.getParameterCount() == 1) {
Class<?> p = m.getParameterTypes()[0];
if (!Throwable.class.isAssignableFrom(p)) {
throw new IllegalStateException("afterThrowing single arg must be Throwable: " + m);
}
}
} Prevention
- Type the single afterThrowing parameter as Throwable or a subclass (Exception, IOException).
- Avoid overloading afterThrowing with non-throwable single args.
- Run a quick reflection smoke test on ThrowsAdvice classes at startup.
When it happens
Trigger: Defining 'public void afterThrowing(String s)' or 'afterThrowing(Integer i)' on a ThrowsAdvice implementation; accidentally overloading afterThrowing with a non-throwable single arg.
Common situations: Copy-paste from a before/afterReturning handler signature; misunderstanding the ThrowsAdvice contract; auto-completed a wrong parameter type.
Related errors
- Invalid afterThrowing signature: four arguments must be Meth
- Unsupported afterThrowing signature: single throwable argume
- Only one afterThrowing method per specific Throwable subclas
- At least one handler method must be found in class [{throwsA
- Target required after globals
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/80b32b2cc638b7ee.json.
Report an issue: GitHub.