spring-projects/spring-framework · error · IllegalArgumentException
Placeholder [{match}] is not valid
Error message
Placeholder [{match}] is not valid What it means
checkForInvalidPlaceholders throws IllegalArgumentException at setter time when setEnterMessage/setExitMessage/setExceptionMessage contains a $[...] token that is not one of the eight allowed placeholders. The valid set is fixed (methodName, targetClassName, targetClassShortName, returnValue, argumentTypes, arguments, exception, invocationTime); any other match of the regex $\[\p{Alpha}+] is rejected.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/interceptor/CustomizableTraceInterceptor.java:397
String[] argumentTypeShortNames = new String[argumentTypes.length];
for (int i = 0; i < argumentTypeShortNames.length; i++) {
argumentTypeShortNames[i] = ClassUtils.getShortName(argumentTypes[i]);
}
matcher.appendReplacement(output,
Matcher.quoteReplacement(StringUtils.arrayToCommaDelimitedString(argumentTypeShortNames)));
}
/**
* Checks to see if the supplied {@code String} has any placeholders
* that are not specified as constants on this class and throws an
* {@code IllegalArgumentException} if so.
*/
private static void checkForInvalidPlaceholders(String message) throws IllegalArgumentException {
Matcher matcher = PATTERN.matcher(message);
while (matcher.find()) {
String match = matcher.group();
if (!ALLOWED_PLACEHOLDERS.contains(match)) {
throw new IllegalArgumentException("Placeholder [" + match + "] is not valid");
}
}
}
}
View on GitHub (pinned to e8729d0438)
Solutions
- Use only the documented placeholder constants (e.g. $[methodName], $[targetClassName], $[returnValue]).
- Respect per-message restrictions: enterMessage cannot use $[returnValue], $[exception], or $[invocationTime].
- Reference CustomizableTraceInterceptor.PLACEHOLDER_* constants instead of hardcoding strings.
Example fix
// before
interceptor.setEnterMessage("Entering $[method] on $[target]");
// after
interceptor.setEnterMessage(
"Entering " + CustomizableTraceInterceptor.PLACEHOLDER_METHOD_NAME +
" on " + CustomizableTraceInterceptor.PLACEHOLDER_TARGET_CLASS_NAME); Defensive patterns
Strategy: validation
Validate before calling
static final Set<String> ALLOWED = CustomizableTraceInterceptor.ALLOWED_PLACEHOLDERS;
void validate(String msg) {
Matcher m = Pattern.compile("\\$\\[\\p{Alpha}+]").matcher(msg);
while (m.find()) {
if (!ALLOWED.contains(m.group())) {
throw new IllegalArgumentException("bad placeholder: " + m.group());
}
}
} Prevention
- Reference PLACEHOLDER_* constants rather than typing placeholder strings.
- Externalise trace templates into a config file covered by a startup test.
- Review the per-message placeholder restrictions in the Javadoc.
When it happens
Trigger: Calling interceptor.setEnterMessage("Entering $[method] for $[target]") where $[method] and $[target] are not recognised placeholders (the real names are $[methodName] and $[targetClassName]).
Common situations: Misspelling a placeholder; copying an example from an outdated tutorial; using a $[var] shell-style variable that happens to match the regex.
Related errors
- Class '{}' is not an @AspectJ aspect
- IntroductionInfo defines no interfaces to introduce: {introd
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Only afterReturning advice can be used to bind a return valu
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/a63147d9a998af8a.json.
Report an issue: GitHub.