{"record":{"id":"d66f0e2abc0704b6","repo":"quarkusio/quarkus","slug":"multiple-extension-methods-match-0-params-and-the","errorCode":null,"errorMessage":"Multiple extension methods match 0 params and the name %s: %s. Specify priorities to avoid this problem.","messagePattern":"Multiple extension methods match 0 params and the name (.+?): (.+?)\\. Specify priorities to avoid this problem\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"independent-projects/qute/generator/src/main/java/io/quarkus/qute/generator/ExtensionMethodGenerator.java","lineNumber":360,"sourceCode":"                        for (Map.Entry<String, List<NamespaceExtensionMethodInfo>> mne : matchingName.entrySet()) {\n                            String matchName = mne.getKey();\n                            boolean matchAny = matchName.equals(TemplateExtension.ANY);\n\n                            bc.block(nested -> {\n                                // Test name\n                                if (!matchAny) {\n                                    nested.ifNot(nested.exprEquals(name, Const.of(matchName)),\n                                            notMatching -> notMatching.break_(nested));\n                                }\n                                // Test number of evaluated params\n                                nested.if_(nested.ne(paramsCount, Const.of(numberOfParams)),\n                                        notEqual -> notEqual.break_(nested));\n\n                                List<NamespaceExtensionMethodInfo> methods = mne.getValue();\n                                if (numberOfParams == 0) {\n                                    // No params -> there must be exactly one extension method\n                                    if (methods.size() > 1) {\n                                        throw new IllegalStateException(\n                                                \"Multiple extension methods match 0 params and the name %s: %s. Specify priorities to avoid this problem.\"\n                                                        .formatted(matchName, methods));\n                                    }\n                                    nested.return_(doInvokeNoParams(nested, name, evalContext, methods.get(0)));\n                                } else {\n                                    evaluateAndInvoke(nested, evalContext, name, methods);\n                                }\n                            });\n                        }\n\n                        // Then handle all methods matching the same number of params and the _same names_\n                        for (Map.Entry<Set<String>, List<NamespaceExtensionMethodInfo>> mne : matchingNames.entrySet()) {\n                            Set<String> matchNames = mne.getKey();\n\n                            bc.block(nested -> {\n                                // Test that any of the names matches\n                                nested.block(nested2 -> {\n                                    for (String matchName : matchNames.stream().sorted().toList()) {","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/qute/generator/src/main/java/io/quarkus/qute/generator/ExtensionMethodGenerator.java#L342-L378","documentation":"In a namespace (e.g. 'config' or 'time'), when a name with zero parameters matches more than one extension method, Qute cannot decide which one to invoke. It throws IllegalStateException unless distinct priorities disambiguate the methods.","triggerScenarios":"Registering two or more namespace extension methods with the same name, zero parameters, and equal priority; raised in generateNamespaceResolver during template class generation.","commonSituations":"Two @TemplateExtension(matchName=\"now\", namespace=\"time\") methods in different classes; duplicated extension methods after merging libraries; same-name overloads that differ only in return type.","solutions":["Set distinct priorities via @TemplateExtension(priority = N) so one method wins","Rename one of the conflicting methods","Remove the duplicate extension method"],"exampleFix":"// before\n@TemplateExtension(namespace = \"time\", matchName = \"now\")\nstatic String now() { ... }\n// duplicated in another class\n// after\n@TemplateExtension(namespace = \"time\", matchName = \"now\", priority = 10)\nstatic String now() { ... }","handlingStrategy":"validation","validationCode":"// Detect duplicate no-arg namespace extensions with same name at app startup test:\nMap<String,Long> dup = methods.stream().collect(groupingBy(m -> name(m), counting()));\nif (dup.values().stream().anyMatch(c -> c > 1)) throw new IllegalStateException(\"Ambiguous namespace extension\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Assign explicit priorities to all namespace extensions","Avoid duplicate names across extension classes","Run a template smoke test in CI that renders affected expressions"],"tags":["qute","namespace","ambiguity","build-time"],"backgroundTag":"ambiguous-template-extension","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"}