quarkusio/quarkus · error · IllegalArgumentException
Parameter with index <i> of method '<beanMethod>' found in e
Error message
Parameter with index <i> of method '<beanMethod>' found in expression '<expression>' in the @PreAuthorize annotation on method <method> of class <class> is not of type String
What it means
When generating a security check from a Spring Security @PreAuthorize SpEL expression, a quoted literal argument (e.g. @bean.method('x')) must match the corresponding bean method parameter type. The processor found the parameter at index i is not String, so the generated invocation would be type-unsafe, and the build fails.
Source
Thrown at extensions/spring-security/deployment/src/main/java/io/quarkus/spring/security/deployment/BeanMethodInvocationGenerator.java:172
mc.body(bc -> {
LocalVar arcContainer = bc.localVar("arcContainer", bc
.invokeStatic(MethodDesc.of(Arc.class, "container", ArcContainer.class)));
LocalVar instanceHandle = bc.localVar("instanceHandle", bc.invokeInterface(
MethodDesc.of(ArcContainer.class, "instance", InstanceHandle.class, String.class),
arcContainer, Const.of(beanName)));
LocalVar bean = bc.localVar("bean", bc
.invokeInterface(MethodDesc.of(InstanceHandle.class, "get", Object.class), instanceHandle));
LocalVar castedBean = bc.localVar("castedBean", bc.cast(bean, classDescOf(beanClassInfo)));
List<Expr> argHandles = new ArrayList<>(finalBeanMethodArgumentExpressions.length);
for (int i = 0; i < finalBeanMethodArgumentExpressions.length; i++) {
String argumentExpression = finalBeanMethodArgumentExpressions[i];
String trimmedArgumentExpression = argumentExpression.trim();
if (argumentExpression.startsWith("'") && argumentExpression.endsWith("'")) { // hard coded string case
if (!DotNames.STRING.equals(matchingBeanMethod.parameterType(i).name())) {
throw new IllegalArgumentException("Parameter with index " + i + " of method '" + beanMethodName
+ "' found in expression '" + trimmedArgumentExpression
+ "' in the @PreAuthorize annotation on method " + securedMethodInfo.name()
+ " of class "
+ securedMethodInfo.declaringClass() + " is not of type String");
}
argHandles.add(Const.of(argumentExpression.replace("'", "")));
} else if (trimmedArgumentExpression.matches(METHOD_PARAMETER_REGEX)) { // secured method's parameter case
checkRequiresMethodArguments[0] = true;
Matcher parameterMatcher = METHOD_PARAMETER_PATTERN.matcher(trimmedArgumentExpression);
if (!parameterMatcher.find()) { // should never happen
throw createGenericMalformedException(securedMethodInfo, expression);
}
// this is the index of the parameter we care about
int parameterIndex = getParameterIndex(securedMethodInfo, parameterMatcher.group(1), expression);
DotName expectedType = securedMethodInfo.parameterType(parameterIndex).name();View on GitHub (pinned to e1c734241f)
Solutions
- Change the bean method parameter type to String, or remove the quotes so the literal matches a non-String parameter
- Overload the bean method with a String-argument variant
- Rewrite the SpEL to reference the secured method's parameters (#id) instead of literals
- Convert the literal syntax to match the target parameter type
Example fix
// before: @PreAuthorize("@authz.hasRole('ADMIN')") with bean method
public boolean hasRole(int level)
// after
public boolean hasRole(String level) // or call hasRole(1) without quotes Defensive patterns
Strategy: validation
Validate before calling
// check literal argument vs bean method signature
if (isQuotedLiteral(expr) && !beanMethod.getParameterTypes()[i].equals(String.class)) {
throw new IllegalStateException("Literal '" + expr + "' does not match non-String param " + i);
} Prevention
- Match quoted literals only with String parameters
- Unquote literals for primitive/non-String parameters
- Keep bean method signatures used in @PreAuthorize simple and reviewed
When it happens
Trigger: @PreAuthorize("@authz.check('literal')") where the target bean method's parameter at that position is not String (e.g. int, long, enum).
Common situations: SpEL expressions copied from Spring apps where the target method signature changed; wrong bean method matched due to overloads; hardcoded literal quoting mismatched with a non-String parameter.
Related errors
- Parameter with index <i> of method '<beanMethod>' found in e
- Could not match a unique method name '<methodName>' for bean
- Could not find a public, boolean returning method named '<me
- Expression: '<expression>' in the @PreAuthorize annotation o
- Bean named '<beanName>' found in expression '<expression>' i
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/189220398e9eb3d8.
Report an issue: GitHub.