{"record":{"id":"094f2d3b1ebe5164","repo":"quarkusio/quarkus","slug":"functionname-must-be-either-function-map-string","errorCode":null,"errorMessage":"`functionName` must be either `Function<Map<String, Object>, List<Consumer<BuildChainBuilder>>>` or `Function<Map<String, Object>, Map.Entry<List<Consumer<BuildChainBuilder>>, List<Consumer<BuildExecutionBuilder>>>>`","messagePattern":"`functionName` must be either `Function<Map<String, Object>, List<Consumer<BuildChainBuilder>>>` or `Function<Map<String, Object>, Map\\.Entry<List<Consumer<BuildChainBuilder>>, List<Consumer<BuildExecutionBuilder>>>>`","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java","lineNumber":142,"sourceCode":"            Class<?> augmentor = getOrCreateAugmentClassLoader().loadClass(AUGMENTOR);\n            Function<Object, Object> function = (Function<Object, Object>) getOrCreateAugmentClassLoader()\n                    .loadClass(functionName)\n                    .getDeclaredConstructor()\n                    .newInstance();\n            var res = function.apply(props);\n            if (res instanceof List l) {\n                return (AugmentAction) augmentor.getConstructor(CuratedApplication.class, List.class, List.class)\n                        .newInstance(this, l, Collections.emptyList());\n            } else if (res instanceof Map.Entry e) {\n                var key = e.getKey();\n                var value = e.getValue();\n                if ((key instanceof List l1) && (value instanceof List l2)) {\n                    return (AugmentAction) augmentor\n                            .getConstructor(CuratedApplication.class, List.class, List.class, List.class)\n                            .newInstance(this, l1, l2, Collections.emptyList());\n                }\n            }\n            throw new IllegalArgumentException(\n                    \"`functionName` must be either `Function<Map<String, Object>, List<Consumer<BuildChainBuilder>>>` or `Function<Map<String, Object>, Map.Entry<List<Consumer<BuildChainBuilder>>, List<Consumer<BuildExecutionBuilder>>>>`\");\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private Object runInCl(String consumerName, Map<String, Object> params, QuarkusClassLoader cl) {\n        ClassLoader old = Thread.currentThread().getContextClassLoader();\n        try {\n            Thread.currentThread().setContextClassLoader(cl);\n            Class<? extends BiConsumer<CuratedApplication, Map<String, Object>>> clazz = (Class<? extends BiConsumer<CuratedApplication, Map<String, Object>>>) cl\n                    .loadClass(consumerName);\n            BiConsumer<CuratedApplication, Map<String, Object>> biConsumer = clazz.getDeclaredConstructor().newInstance();\n            biConsumer.accept(this, params);\n            return biConsumer;\n        } catch (RuntimeException e) {\n            throw e;","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java#L124-L160","documentation":"CuratedApplication.createAugmentor looks up a user-supplied augmentor Function class by name (`functionName` system/config property), loads it in the augmentor classloader, and checks whether it implements the accepted generic signatures. If the loaded class is not a Function producing either List<Consumer<BuildChainBuilder>> or Map.Entry<List<Consumer<BuildChainBuilder>>, List<Consumer<BuildExecutionBuilder>>>, it throws this IllegalArgumentException. It is a contract mismatch between the configured augmentor class and the bootstrap API.","triggerScenarios":"Setting a `functionName`-style property (e.g. via app builder AugmentAction configuration used by app/initAugmentAction/handleDevServices callers) to a class that is not a Function with one of the two required signatures, or one whose type parameters were erased/mismatched so the reflective type check in createAugmentor fails.","commonSituations":"Custom tooling or dev-services integration registering an augmentor class that implements the wrong interface (e.g. BiFunction or old Quarkus augmentor API), pointing at a stale class from an older Quarkus version, or a typo causing the wrong class to be loaded.","solutions":["Make the augmentor class implement `Function<Map<String, Object>, List<Consumer<BuildChainBuilder>>>` (or the Map.Entry variant including build-execution consumers).","Check the value configured for the augmentor function name property and correct any typo or stale fully-qualified class name.","Rebuild against the Quarkus version in use; older augmentor signatures were removed and must be migrated.","If you only need a custom augmentor, prefer the standard QuarkusBootstrap.builder().build().createAugmentor() default instead of a custom functionName."],"exampleFix":"// before\npublic class MyAugmentor implements Function<Map<String, Object>, String> { ... }\n// after\npublic class MyAugmentor implements Function<Map<String, Object>, List<Consumer<BuildChainBuilder>>> {\n    public List<Consumer<BuildChainBuilder>> apply(Map<String, Object> params) { ... }\n}","handlingStrategy":"validation","validationCode":"Class<?> c = Class.forName(functionClassName);\nif (!java.util.function.Function.class.isAssignableFrom(c)) {\n    throw new IllegalArgumentException(functionClassName + \" must implement Function<Map<String,Object>, ...>\");\n}","typeGuard":null,"tryCatchPattern":"try { app.createAugmentor(); } catch (IllegalArgumentException e) { log.error(\"Augmentor function signature invalid: {}\", e.getMessage()); }","preventionTips":["Implement the documented Function signature exactly (List<Consumer<BuildChainBuilder>> or the Map.Entry variant).","Add a unit test that instantiates your augmentor via the same reflective path before packaging."],"tags":["bootstrap","reflection","configuration","augmentaction"],"backgroundTag":"invalid-function-signature","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"}