{"id":"f59a4db5f7231f69","repo":"spring-projects/spring-framework","slug":"throwing-name-is-neither-a-valid-argument-nam","errorCode":null,"errorMessage":"Throwing name '{}' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. Root cause: {}","messagePattern":"Throwing name '(.+?)' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath\\. Root cause: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java","lineNumber":344,"sourceCode":"\t\tthrow new UnsupportedOperationException(\"Only afterThrowing advice can be used to bind a thrown exception\");\n\t}\n\n\t/**\n\t * We need to hold the throwing name at this level for argument binding calculations,\n\t * this method allows the afterThrowing advice subclass to set the name.\n\t */\n\tprotected void setThrowingNameNoCheck(String name) {\n\t\t// name could be a variable or a type...\n\t\tif (isVariableName(name)) {\n\t\t\tthis.throwingName = name;\n\t\t}\n\t\telse {\n\t\t\t// assume a type\n\t\t\ttry {\n\t\t\t\tthis.discoveredThrowingType = ClassUtils.forName(name, getAspectClassLoader());\n\t\t\t}\n\t\t\tcatch (Throwable ex) {\n\t\t\t\tthrow new IllegalArgumentException(\"Throwing name '\" + name +\n\t\t\t\t\t\t\"' is neither a valid argument name nor the fully-qualified \" +\n\t\t\t\t\t\t\"name of a Java type on the classpath. Root cause: \" + ex);\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected Class<?> getDiscoveredThrowingType() {\n\t\treturn this.discoveredThrowingType;\n\t}\n\n\t@Contract(\"null -> false\")\n\tprivate static boolean isVariableName(@Nullable String name) {\n\t\treturn AspectJProxyUtils.isVariableName(name);\n\t}\n\n\n\t/**\n\t * Do as much work as we can as part of the set-up so that argument binding","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java#L326-L362","documentation":"Thrown by setThrowingNameNoCheck (line 333-349) when the throwing value is not a Java variable name and ClassUtils.forName cannot resolve it as a Throwable type on the aspect's classloader. Non-identifier throwing values are interpreted as fully-qualified exception types used to narrow which exceptions match; failure to load means binding is impossible.","triggerScenarios":"Setting 'throwing' to a string that is neither a valid Java identifier nor a fully-qualified Throwable subtype resolvable by the aspect ClassLoader (typo, wrong package, missing dependency, non-Throwable type).","commonSituations":"Typo in the throwing attribute; using a simple class name instead of fully-qualified; the exception type lives in a jar not present at runtime; refactoring that moved the exception class without updating the aspect config.","solutions":["If throwing should bind a parameter, use the exact advice parameter name (a valid Java identifier).","If throwing is meant to narrow by type, supply the fully-qualified Throwable subtype name and confirm it is on the classpath.","Fix typos/package names and add the missing dependency jar.","Remove the throwing attribute if no exception binding/narrowing is intended."],"exampleFix":"// before\n<aop:after-throwing method=\"onEx\" throwing=\"java.lang.RunntimeException\" pointcut=\"...\"/>\n// after\n<aop:after-throwing method=\"onEx\" throwing=\"java.lang.RuntimeException\" pointcut=\"...\"/>","handlingStrategy":"validation","validationCode":"// Validate a throwing value before setting it: identifier or loadable Throwable type.\nString name = throwingValue.strip();\nboolean ok = AspectJProxyUtils.isVariableName(name);\nif (!ok) {\n    try {\n        Class<?> c = ClassUtils.forName(name, aspectClassLoader);\n        ok = Throwable.class.isAssignableFrom(c);\n    } catch (Throwable t) { ok = false; }\n}\nif (!ok) throw new IllegalArgumentException(\"Invalid throwing value: \" + name);","typeGuard":null,"tryCatchPattern":"try {\n    ((AspectJAfterThrowingAdvice) advice).setThrowingName(name);\n} catch (IllegalArgumentException ex) {\n    throw new IllegalArgumentException(\n        \"'throwing' must be a parameter name or fully-qualified Throwable type on the classpath: \" + name, ex);\n}","preventionTips":["Use the exact advice parameter name as the throwing value when binding.","When narrowing by type, use a fully-qualified Throwable subtype and confirm the jar is present.","Re-check aspect config after refactoring exception class locations."],"tags":["spring-aop","aspectj","after-throwing","argument-binding","classpath"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}