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

  1. Correct the 'arg-names' / 'argNames' value so every token is a legal Java identifier matching a real advice parameter.
  2. Remove trailing commas, empty tokens, and stray whitespace; pass a clean comma-delimited list.
  3. If you intended a type for returning/throwing, put it in the 'returning'/'throwing' attribute instead of arg-names.
  4. 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

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


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