quarkusio/quarkus · error · java.lang.IllegalArgumentException

@PermissionsAllowed annotation placed on method '%s' has 'pa

Error message

@PermissionsAllowed annotation placed on method '%s' has 'params' attribute
                                    '%s' that cannot be matched to any Permission %s '%s' parameter

What it means

Similar to the constructor-param mismatch, but thrown from the code path that matches a @PermissionsAllowed 'params' entry (with a nested expression) against the parameters of the Permission checker method or the custom Permission constructor. When a nested param expression like 'item.id' cannot be matched to any parameter of the Permission class's constructor or the checker, Quarkus throws this IllegalArgumentException naming the secured method, the unmatched expression, the kind of target, and the target name.

Source

Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java:1394

                                        secured method and constructor has formal parameter with name '%1$s'.
                                        """
                                        .formatted(paramName, PermissionSecurityChecksBuilder.toString(securedMethod),
                                                quarkusPermission ? "checker" : "constructor", matchTarget));
                    }
                }
                if (nestedParamExpressions != null) {
                    outer: for (int i = 0; i < nestedParamExpressions.length; i++) {
                        if (nestedParamExpressions[i] != null) {
                            var nestedParamExp = nestedParamExpressions[i];
                            for (SecMethodAndPermCtorIdx match : matches) {
                                if (nestedParamExp.equals(match.nestedParamExpression())) {
                                    continue outer;
                                }
                            }
                            var matchTarget = quarkusPermission
                                    ? PermissionSecurityChecksBuilder.toString(permissionCheckerMethod)
                                    : constructor.declaringClass().name().toString();
                            throw new IllegalArgumentException("""
                                    @PermissionsAllowed annotation placed on method '%s' has 'params' attribute
                                    '%s' that cannot be matched to any Permission %s '%s' parameter
                                    """.formatted(PermissionSecurityChecksBuilder.toString(securedMethod),
                                    params[i] + "." + nestedParamExp, quarkusPermission ? "checker" : "constructor",
                                    matchTarget));
                        }
                    }
                }
            }

            private static String[] getMethodParamConverters(PermissionConverterGenerator paramConverterGenerator,
                    SecMethodAndPermCtorIdx[] matches, MethodInfo securedMethod, int[] methodParamIndexes) {
                var converters = new String[methodParamIndexes.length];
                boolean requireConverter = false;
                for (SecMethodAndPermCtorIdx match : matches) {
                    if (match.nestedParamExpression() != null) {
                        requireConverter = true;
                        converters[match.constructorParamIdx()] = paramConverterGenerator

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add or rename a parameter on the Permission constructor / @PermissionChecker method so the nested expression root matches a formal parameter name.
  2. Simplify the params expression to a level the target actually exposes (e.g. use "order" instead of "order.customerId" if only the object is available).
  3. Ensure the nested property exists on the passed object type and that parameter names are retained at compile time (-parameters).

Example fix

// before
@PermissionsAllowed(value = "audit", params = { "req.headers" }) // checker takes 'request' only

// after
@PermissionsAllowed(value = "audit", params = { "request" })
public void handle(RequestContext request, Permission perm) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Check nested expression roots against checker/constructor signatures before deploying:
// For params "order.customerId": the checker/constructor must have a parameter named 'order'.

Prevention

When it happens

Trigger: @PermissionsAllowed(value="p", params={"order.customerId"}) where the Permission class constructor or @PermissionChecker method has no parameter named 'order' (or the nested path does not resolve against it).

Common situations: Deep-nesting property paths that the constructor/checker does not expose; renaming fields after refactoring; using params with a Quarkus permission checker whose method signature lacks the referenced argument.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/672546b56064a69a. Report an issue: GitHub.