{"record":{"id":"154f45f11d099661","repo":"quarkusio/quarkus","slug":"s-must-have-autodetected-params","errorCode":null,"errorMessage":"'%s' must have autodetected params","messagePattern":"'(.+?)' must have autodetected params","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java","lineNumber":1085,"sourceCode":"        }\n\n        private Function<Object[], Permission> createComputedPermission(PermissionCacheKey permissionCacheKey) {\n            return recorder.createComputedPermission(permissionCacheKey.permissionKey.name,\n                    permissionCacheKey.permissionKey.classSignature(), permissionCacheKey.permissionKey.actions(),\n                    permissionCacheKey.passActionsToConstructor, permissionCacheKey.methodParamIndexes(),\n                    permissionCacheKey.methodParamConverters, paramConverterGenerator.getConverterNameToMethodHandle());\n        }\n\n        private RuntimeValue<Permission> createCustomPermission(PermissionCacheKey permissionCacheKey) {\n            return recorder.createPermission(permissionCacheKey.permissionKey.name,\n                    permissionCacheKey.permissionKey.classSignature(), permissionCacheKey.permissionKey.actions(),\n                    permissionCacheKey.passActionsToConstructor);\n        }\n\n        private RuntimeValue<Permission> createStringPermission(PermissionKey permissionKey) {\n            if (permissionKey.notAutodetectParams()) {\n                // validate - no point to specify params as string permission only accept name and actions\n                throw new IllegalArgumentException(String.format(\"'%s' must have autodetected params\", STRING_PERMISSION));\n            }\n            return recorder.createStringPermission(permissionKey.name, permissionKey.actions());\n        }\n\n        private static final class LogicalOrPermissionPredicate {\n            private final Set<PermissionWrapper> operands = new LinkedHashSet<>();\n\n            private LogicalOrPermissionPredicate or(PermissionWrapper permission) {\n                operands.add(permission);\n                return this;\n            }\n\n            private List<Function<Object[], Permission>> asComputedPermissions(SecurityCheckRecorder recorder) {\n                final List<Function<Object[], Permission>> computedPermissions = new ArrayList<>();\n                for (PermissionWrapper wrapper : operands) {\n                    if (wrapper.isComputed()) {\n                        computedPermissions.add(wrapper.computedPermission);\n                    } else {","sourceCodeStart":1067,"sourceCodeEnd":1103,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java#L1067-L1103","documentation":"Quarkus builds a StringPermission (name + actions only) at runtime for permissions backed by @PermissionChecker or plain values. StringPermission does not support permission parameters; if a PermissionKey configured with a custom string permission class also declares params (notAutodetectParams), createStringPermission throws this IllegalArgumentException during recording. Custom Permission classes must instead autodetect their constructor parameters.","triggerScenarios":"A @PermissionsAllowed entry whose Permission class is java.lang.StringPermission (or otherwise resolved to a string permission) while 'params' attribute values are supplied, i.e. explicit parameters on a permission that only accepts name and actions.","commonSituations":"Adding params to a plain string permission by mistake; copying a custom-permission example but leaving clazz as StringPermission; misunderstanding that params require a custom Permission implementation with a matching constructor.","solutions":["Remove the 'params' attribute from this @PermissionsAllowed instance — string permissions accept only name and actions.","Use a custom Permission implementation class (clazz attribute) whose constructor accepts the parameters, so params are matched to its constructor instead of the string permission.","If you meant to bind method arguments, place the annotation on a method and let Quarkus autodetect params for a permission class that supports them."],"exampleFix":"// before\n@PermissionsAllowed(value = \"get\", params = { \"id\" }) // StringPermission has no param constructor\n\n// after (custom permission)\n@PermissionsAllowed(value = \"get\", clazz = GetPermission.class, params = { \"id\" })\n// where GetPermission has a constructor GetPermission(String name, Long id)","handlingStrategy":"validation","validationCode":"// String permissions must not declare params:\nboolean invalid = clazz == StringPermission.class && params != null && params.length > 0;\nif (invalid) throw new IllegalArgumentException(\"StringPermission cannot accept params; use a custom Permission class\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never combine the default String permission with the params attribute.","Use a custom Permission class with a matching constructor whenever parameters are needed.","Keep a checklist: params => custom clazz; no params => StringPermission."],"tags":["quarkus","security","stringpermission","params"],"backgroundTag":"permission-params-unsupported","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}