spring-projects/spring-framework · error · IllegalArgumentException
'argumentNames' property of AbstractAspectJAdvice contains a
Error message
'argumentNames' property of AbstractAspectJAdvice contains an argument name '{}' that is not a valid Java identifier What it means
Thrown by setArgumentNamesFromStringArray (line 262-272) when one of the supplied argument names fails the isVariableName check (delegated to AspectJProxyUtils.isVariableName). Each argument name must be a syntactically valid Java identifier; this guards later binding of pointcut parameters to advice parameters. It fires during advice setup, typically when parsing an XML 'arg-names' attribute or annotation value.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java:268
*/
public void setArgumentNames(String argumentNames) {
String[] tokens = StringUtils.commaDelimitedListToStringArray(argumentNames);
setArgumentNamesFromStringArray(tokens);
}
/**
* Set by the creator of this advice object if the argument names are known.
* <p>This could be for example because they have been explicitly specified in XML
* or in an advice annotation.
* @param argumentNames list of argument names
*/
public void setArgumentNamesFromStringArray(@Nullable String... argumentNames) {
this.argumentNames = new String[argumentNames.length];
for (int i = 0; i < argumentNames.length; i++) {
String argumentName = argumentNames[i];
this.argumentNames[i] = argumentName != null ? argumentName.strip() : null;
if (!isVariableName(this.argumentNames[i])) {
throw new IllegalArgumentException(
"'argumentNames' property of AbstractAspectJAdvice contains an argument name '" +
this.argumentNames[i] + "' that is not a valid Java identifier");
}
}
if (this.aspectJAdviceMethod.getParameterCount() == this.argumentNames.length + 1) {
// 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;
}View on GitHub (pinned to e8729d0438)
Solutions
- Correct the 'arg-names' / 'argNames' value so every token is a legal Java identifier matching a real advice parameter.
- Remove trailing commas, empty tokens, and stray whitespace; pass a clean comma-delimited list.
- If you intended a type for returning/throwing, put it in the 'returning'/'throwing' attribute instead of arg-names.
- Drop the arg-names attribute entirely and let Spring discover names (compile with -parameters) when the mapping is unambiguous.
Example fix
// before <aop:after-returning method="log" pointcut="args(req)" returning="ret" arg-names="com.example.Result, req"/> // after <aop:after-returning method="log" pointcut="args(req)" returning="ret" arg-names="ret, req"/>
Defensive patterns
Strategy: validation
Validate before calling
// Validate arg-names tokens before calling setArgumentNames(...).
for (String token : argNames.split(",")) {
String t = token.strip();
if (t.isEmpty() || !t.chars().limit(1).allMatch(Character::isJavaIdentifierStart())
|| !t.chars().skip(1).allMatch(Character::isJavaIdentifierPart)) {
throw new IllegalArgumentException("Invalid arg-names token: " + token);
}
} Try / catch
try {
advice.setArgumentNames(argNames);
} catch (IllegalArgumentException ex) {
// surface a clearer config error pointing at the offending element
throw new IllegalArgumentException("Bad 'arg-names' in aspect config: " + argNames, ex);
} Prevention
- Treat arg-names as a comma-delimited list of exact Java identifiers only.
- Keep arg-names in sync with the advice method signature; update on every signature change.
- Prefer compiling with -parameters and omitting arg-names when possible.
- Put type narrowing in returning/throwing, never in arg-names.
When it happens
Trigger: Calling setArgumentNames("foo,123bad,_ok,x y") or setArgumentNamesFromStringArray(...) with any token that is null, empty, contains spaces/operators, or starts with a digit. Spring's XML <aop:aspect> parser and @AspectJ processing pass the 'argNames' / 'arg-names' attribute straight into this method.
Common situations: Typo in the 'arg-names' XML attribute (e.g. trailing comma, stray space, comma between names becoming 'a, ,b'); copying a fully-qualified type name into arg-names instead of the variable name; mixing returning/throwing type names where variable names are expected; encoding/locale issues producing non-identifier characters.
Related errors
- Advice method [{}] requires {} arguments to be bound by name
- Expecting to find {} arguments to bind by name in advice, bu
- Returning argument name '{}' was not bound in advice argumen
- Throwing argument name '{}' was not bound in advice argument
- Not enough arguments in method to satisfy binding of returni
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/c6346c7b252b0cef.json.
Report an issue: GitHub.