{"record":{"id":"1335087759f96165","repo":"quarkusio/quarkus","slug":"permissionsallowed-annotation-placed-on-the-s","errorCode":null,"errorMessage":"@PermissionsAllowed annotation placed on the '%s' has inclusive relation between its permissions.\n                                            The '%s' permission has been matched with @PermissionChecker '%s', therefore you must also define\n                                            a @PermissionChecker for '%s' permissions.\n                                            ","messagePattern":"@PermissionsAllowed annotation placed on the '(.+?)' has inclusive relation between its permissions\\.\n                                            The '(.+?)' permission has been matched with @PermissionChecker '(.+?)', therefore you must also define\n                                            a @PermissionChecker for '(.+?)' permissions\\.\n                                            ","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java","lineNumber":677,"sourceCode":"                for (PermissionNameAndChecker checkerPermission : checkerPermissions) {\n                    String permissionName = PermissionToActionUtil.parse(checkerPermission.permissionName).name();\n                    for (var e : permissionToActions.entrySet()) {\n                        PermissionNameAndChecker permissionNameKey = e.getKey();\n                        // look for permission names that match our permission checker value (before action-to-perm separator)\n                        // for example: read:it\n                        if (permissionNameKey.checker == null && permissionNameKey.permissionName.equals(permissionName)) {\n                            boolean hasActions = e.getValue() != null && !e.getValue().isEmpty();\n                            final String permissionsJoinedWithActions;\n                            if (hasActions) {\n                                permissionsJoinedWithActions = e.getValue()\n                                        .stream()\n                                        .map(action -> permissionNameKey.permissionName + PERMISSION_TO_ACTION_SEPARATOR\n                                                + action)\n                                        .collect(Collectors.joining(\", \"));\n                            } else {\n                                permissionsJoinedWithActions = permissionNameKey.permissionName;\n                            }\n                            throw new RuntimeException(\n                                    \"\"\"\n                                            @PermissionsAllowed annotation placed on the '%s' has inclusive relation between its permissions.\n                                            The '%s' permission has been matched with @PermissionChecker '%s', therefore you must also define\n                                            a @PermissionChecker for '%s' permissions.\n                                            \"\"\"\n                                            .formatted(toString(annotationTarget), permissionName,\n                                                    toString(checkerPermission.checker.checkerMethod),\n                                                    permissionsJoinedWithActions));\n                        }\n                    }\n                }\n            }\n\n            for (var permissionToAction : permissionToActions.entrySet().stream().sorted(PERMISSION_TO_ACTION_COMPARATOR)\n                    .toList()) {\n                final var permissionNameKey = permissionToAction.getKey();\n                final var permissionActions = permissionToAction.getValue();\n                final var key = new PermissionKey(permissionNameKey.permissionName, permissionActions, params, classType,","sourceCodeStart":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java#L659-L695","documentation":"When @PermissionsAllowed uses inclusive permission relations and one permission in the group is backed by a @PermissionChecker method, Quarkus requires every permission in that group to have a matching @PermissionChecker. If a permission (e.g. 'delete') matched a checker but a sibling permission in the same inclusive annotation has none, deployment fails with this message naming the annotation target, matched permission, existing checker, and the missing permission set.","triggerScenarios":"Using @PermissionsAllowed(value={...}, inclusive=true) where permission 'a' resolves to a @PermissionChecker method but sibling permission 'b' in the same annotation resolves to a plain StringPermission (no checker).","commonSituations":"Mixing @PermissionChecker-annotated producer methods with plain string permissions in one inclusive annotation; adding a new permission to an existing inclusive group without adding its checker; typos so a permission name no longer matches any checker method.","solutions":["Define a @PermissionChecker method for every permission listed in the inclusive @PermissionsAllowed annotation, e.g. add a method annotated @PermissionChecker(\"missing-permission\") returning PermissionChecker in a CDI bean.","Set inclusive=false on the annotation if an OR/one-of relation (each permission evaluated independently) is actually intended.","Rename the permission in @PermissionsAllowed so it no longer accidentally matches a checker, if plain string permissions are wanted."],"exampleFix":"// before\n@PermissionsAllowed(value = {\"read\", \"delete\"}, inclusive = true) // 'read' has a checker, 'delete' does not\n\n// after — add to a CDI bean:\n@PermissionChecker(\"delete\")\nPermissionChecker deleteChecker() { return ctx -> ctx.getSubject().map(...).orElse(false); }","handlingStrategy":"validation","validationCode":"// Convention: maintain a single @PermissionChecker per permission name in one config class,\n// and a test that every permission listed in inclusive @PermissionsAllowed annotations has a checker.\n// grep your sources: every @PermissionsAllowed(value={...}, inclusive=true) name must have @PermissionChecker(name)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["For inclusive=true groups, define a @PermissionChecker for every listed permission before writing the annotation.","Prefer inclusive=false (default OR semantics) unless all-permissions-required is truly needed.","Centralize permission names as constants to avoid typos that break checker matching."],"tags":["quarkus","security","permissionchecker","inclusive-relation"],"backgroundTag":"permission-checker-missing","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}