quarkusio/quarkus · error · java.lang.IllegalArgumentException
@PermissionAllowed instance that accepts method arguments mu
Error message
@PermissionAllowed instance that accepts method arguments must be placed on a method
What it means
A @PermissionsAllowed instance that consumes secured method arguments (computed permission, i.e. isComputed with param converters) must be placed on a method — the code needs MethodInfo of the secured method to capture argument values. If such a permission is placed on a class (or other non-method target), PermissionCacheKey construction throws this IllegalArgumentException at build time.
Source
Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java:1313
}
private static boolean isNotDefaultStringPermission(Type classType) {
return !STRING_PERMISSION.equals(classType.name());
}
}
private static final class PermissionCacheKey {
private final int[] methodParamIndexes;
private final PermissionKey permissionKey;
private final boolean computed;
private final boolean passActionsToConstructor;
private final String[] methodParamConverters;
private PermissionCacheKey(PermissionKey permissionKey, AnnotationTarget securedTarget, MethodInfo constructor,
PermissionConverterGenerator paramConverterGenerator) {
if (isComputed(permissionKey, constructor)) {
if (securedTarget.kind() != AnnotationTarget.Kind.METHOD) {
throw new IllegalArgumentException(
"@PermissionAllowed instance that accepts method arguments must be placed on a method");
}
MethodInfo securedMethod = securedTarget.asMethod();
// computed permission
this.permissionKey = permissionKey;
this.computed = true;
final boolean isSecondParamStringArr = !secondParamIsNotStringArr(constructor);
// determine if we want to pass actions param to Permission constructor
if (isSecondParamStringArr && !permissionKey.isQuarkusPermission()) {
int foundIx = findSecuredMethodParamIndex(securedMethod, constructor, 1,
permissionKey.paramsRemainder, permissionKey.params, -1, paramConverterGenerator.index)
.methodParamIdx();
// if (foundIx == -1) is false then user assigned second constructor param to a method param
this.passActionsToConstructor = foundIx == -1;
} else {
this.passActionsToConstructor = false;View on GitHub (pinned to e1c734241f)
Solutions
- Move the @PermissionsAllowed annotation with params from the class to the specific method whose arguments it needs.
- If class-wide security is needed, put a param-less @PermissionsAllowed (e.g. a plain permission name backed by @PermissionChecker) at class level and keep parameterized annotations on methods.
Example fix
// before
@PermissionsAllowed(value = "get", params = { "id" })
public class DocumentService { ... }
// after
public class DocumentService {
@PermissionsAllowed(value = "get", params = { "id" })
public Document get(Long id) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
// Rule: @PermissionsAllowed with params must live on a method, not a class. // In an ArchUnit-style test: // methods annotated @PermissionsAllowed with params attribute must have annotationTarget() == METHOD.
Prevention
- Only place param-bearing @PermissionsAllowed on methods.
- Use param-less annotations (or @PermissionChecker-backed ones) for class-level security.
- Document the placement rule in team coding guidelines.
When it happens
Trigger: Placing @PermissionsAllowed with a 'params' attribute referencing method arguments (computed permission) at class level, where securedTarget.kind() != METHOD.
Common situations: Hoisting a method-level annotation to the class to 'share' it; IDE quick-fix moving annotations; misunderstanding that class-level annotations apply to all methods and can use their params.
Related errors
- Invalid @PermissionsAllowed value '%s': %s
- Method '%s' was annotated with '@PermissionsAllowed', but no
- Class '%s' was annotated with '@PermissionsAllowed', but no
- Method '%s#%s' parameter '%s' cannot be converted to a Permi
- Method '%s#%s' parameter '%s' cannot be mapped to a Permissi
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/9cf72ec8e80810c5.
Report an issue: GitHub.