{"record":{"id":"ad7b97f879de714c","repo":"quarkusio/quarkus","slug":"multiple-extension-methods-match-0-params-and-the-ad7b97","errorCode":null,"errorMessage":"Multiple extension methods match 0 params and the names %s: %s. Specify priorities to avoid this problem.","messagePattern":"Multiple extension methods match 0 params and the names (.+?): (.+?)\\. 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":392,"sourceCode":"\n                            bc.block(nested -> {\n                                // Test that any of the names matches\n                                nested.block(nested2 -> {\n                                    for (String matchName : matchNames.stream().sorted().toList()) {\n                                        nested2.if_(nested2.exprEquals(name, Const.of(matchName)),\n                                                namesMatch -> namesMatch.break_(nested2));\n                                    }\n                                    nested2.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 names %s: %s. Specify priorities to avoid this problem.\"\n                                                        .formatted(matchNames, 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                        // Next handle all matchRegex methods\n                        for (NamespaceExtensionMethodInfo em : extensionMethodForParams) {\n                            if (em.matchesRegex()) {\n                                bc.block(nested -> {\n                                    // Test regexp\n                                    FieldDesc patternField = FieldDesc.of(cc.type(),\n                                            PATTERN + \"_\" + sha1(em.method().toString()), Pattern.class);\n                                    Expr pattern = cc.this_().field(patternField);","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/qute/generator/src/main/java/io/quarkus/qute/generator/ExtensionMethodGenerator.java#L374-L410","documentation":"Same ambiguity as the single-name variant, but for a method matching multiple names (@TemplateExtension(matchNames = {...}) or ANY). When resolved with zero arguments, the generated resolver requires exactly one candidate method; multiple matches with equal priority trigger this IllegalStateException.","triggerScenarios":"Two extension methods in the same namespace both declaring matchNames/ANY matching the same name, both invocable with zero params and equal priority; raised in generateNamespaceResolver.","commonSituations":"A catch-all ANY method colliding with a specific matchNames method in the same namespace; registering the same extension class twice; two libraries each contributing a multi-name namespace extension.","solutions":["Give one method a higher priority via @TemplateExtension(priority = N)","Narrow the matchNames/matchRegex of one method so they no longer overlap","Remove the duplicate or catch-all method"],"exampleFix":"// before\n@TemplateExtension(namespace = \"cfg\", matchNames = {\"a\", \"b\"})\nstatic String get(String name) { ... }\n@TemplateExtension(namespace = \"cfg\", matchNames = {\"b\", \"c\"})\nstatic String get2(String name) { ... }\n// after\n@TemplateExtension(namespace = \"cfg\", matchNames = {\"a\", \"b\"}, priority = 5)\nstatic String get(String name) { ... }","handlingStrategy":"validation","validationCode":"// Ensure multi-name extensions don't overlap and have distinct priorities:\nassert distinctPriorities(multiNameExtensions) : \"Multiple 0-param matches for the same names\";","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give ANY/matchNames extensions a distinct high priority","Keep catch-all extensions separate from specific ones","Test namespaces that mix specific and ANY extensions"],"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"}