{"record":{"id":"a1fcc77451670ccd","repo":"quarkusio/quarkus","slug":"failed-to-create-permission-constructor-method-par","errorCode":null,"errorMessage":"Failed to create Permission constructor method parameter converter","messagePattern":"Failed to create Permission constructor method parameter converter","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityCheckRecorder.java","lineNumber":420,"sourceCode":"        runtimeConfigReady = true;\n    }\n\n    public void unsetRuntimeConfigReady(ShutdownContext shutdownContext) {\n        shutdownContext.addShutdownTask(new Runnable() {\n            @Override\n            public void run() {\n                runtimeConfigReady = false;\n            }\n        });\n    }\n\n    public RuntimeValue<MethodHandle> createPermissionMethodConverter(String methodName, RuntimeValue<Class<?>> clazz) {\n        try {\n            var handle = MethodHandles.publicLookup().findStatic(clazz.getValue(), methodName,\n                    MethodType.methodType(Object.class, Object.class));\n            return new RuntimeValue<>(handle);\n        } catch (NoSuchMethodException | IllegalAccessException e) {\n            throw new RuntimeException(\"Failed to create Permission constructor method parameter converter\", e);\n        }\n    }\n\n    public RuntimeValue<Class<?>> loadClassRuntimeVal(String className) {\n        return new RuntimeValue<>(loadClass(className));\n    }\n\n    private static Object convertMethodParamToPermParam(int i, Object methodArg,\n            Map<String, RuntimeValue<MethodHandle>> converterNameToMethodHandle, String[] formalParamConverters) {\n        var converter = converterNameToMethodHandle.get(formalParamConverters[i]).getValue();\n        try {\n            return converter.invokeExact(methodArg);\n        } catch (Throwable e) {\n            throw new RuntimeException(\n                    \"Failed to convert method argument '%s' to Permission constructor parameter\".formatted(methodArg), e);\n        }\n    }\n","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityCheckRecorder.java#L402-L438","documentation":"createPermissionMethodConverter() looks up a static method (named by methodName) on the given class via MethodHandles.publicLookup(), expecting signature Object -> Object, to convert @PermissionsAllowed method arguments into Permission constructor parameters. If no such accessible static method exists (or it is not accessible to a public lookup), a RuntimeException is thrown at build/startup time.","triggerScenarios":"Using a converter name in @PermissionsAllowed (e.g. @PermissionsAllowed(value=\"...\", converter=\"myConverter\")) where the referenced class has no public static method with that name taking one Object parameter and returning Object.","commonSituations":"Converter method is instance (non-static); method is private or package-private (publicLookup cannot see it); method has a different arity; typo in method name; converter declared on the wrong class.","solutions":["Make the converter method public and static, with signature taking exactly one parameter and returning a value.","Verify the method name passed in the annotation/configuration matches exactly.","Ensure the converter method is visible to a public lookup (public class, public method — not in a private nested class).","Change the method to accept and return the types compatible with the permission constructor parameter."],"exampleFix":"// before\nprivate String normalize(String arg) { return arg.toLowerCase(); }\n// after\npublic static Object normalize(Object arg) { return ((String) arg).toLowerCase(); }","handlingStrategy":"validation","validationCode":"// before configuring the converter, verify lookup works\nMethodHandles.publicLookup().findStatic(ConverterClass.class, \"normalize\",\n    MethodType.methodType(Object.class, Object.class));","typeGuard":null,"tryCatchPattern":"try {\n    var handle = MethodHandles.publicLookup().findStatic(clazz, methodName,\n        MethodType.methodType(Object.class, Object.class));\n} catch (NoSuchMethodException | IllegalAccessException e) {\n    throw new IllegalStateException(\"Converter must be public static Object m(Object)\", e);\n}","preventionTips":["Declare converters as public static with exactly one Object parameter","Ensure the converter class itself is public","Match converter names in annotations/config to method names exactly","Add an annotation-processor-time or test check for the converter signature"],"tags":["security","reflection","methodhandle","permissionsallowed"],"backgroundTag":"converter-method-not-found","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"}