{"record":{"id":"2a9219df5ba34f01","repo":"quarkusio/quarkus","slug":"template-extension-method-declared-on-must-accept-2a9219","errorCode":null,"errorMessage":"Template extension method declared on  must accept at least one parameter to match the base object: ","messagePattern":"Template extension method declared on  must accept at least one parameter to match the base object: ","errorType":"exception","errorClass":"TemplateException","httpStatus":null,"severity":"error","filePath":"independent-projects/qute/generator/src/main/java/io/quarkus/qute/generator/ExtensionMethodGenerator.java","lineNumber":993,"sourceCode":"                    indexed++;\n                    params.add(new Param(method.parameterName(i), parameters.get(i), i, ParamKind.NAME));\n                } else {\n                    indexed++;\n                    params.add(new Param(method.parameterName(i), parameters.get(i), i, ParamKind.EVAL));\n                }\n            }\n            this.params = params;\n\n            if (isNameParameterRequired) {\n                Param nameParam = getFirst(ParamKind.NAME);\n                if (nameParam == null || !nameParam.type.name().equals(DotNames.STRING)) {\n                    throw new TemplateException(\n                            \"Template extension method declared on \" + method.declaringClass().name()\n                                    + \" must accept at least one string parameter to match the name: \" + method);\n                }\n            }\n            if (!hasNamespace && getFirst(ParamKind.BASE) == null) {\n                throw new TemplateException(\n                        \"Template extension method declared on \" + method.declaringClass().name()\n                                + \" must accept at least one parameter to match the base object: \" + method);\n            }\n\n            for (Param param : params) {\n                if (param.kind == ParamKind.ATTR && !param.type.name().equals(DotNames.OBJECT)) {\n                    throw new TemplateException(\n                            \"Template extension method parameter annotated with @TemplateAttribute declared on \"\n                                    + method.declaringClass().name()\n                                    + \" must be of type java.lang.Object: \" + method);\n                }\n            }\n        }\n\n        public List<Type> parameterTypes() {\n            return params.stream().map(p -> p.type).toList();\n        }\n","sourceCodeStart":975,"sourceCodeEnd":1011,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/qute/generator/src/main/java/io/quarkus/qute/generator/ExtensionMethodGenerator.java#L975-L1011","documentation":"A non-namespace template extension method must take the base object as (normally the first) parameter so Qute knows which types it extends. If no BASE parameter exists, the generator cannot bind the method to a target type and throws TemplateException.","triggerScenarios":"Declaring @TemplateExtension without namespace and without any base-object parameter (e.g. only name/attribute params); detected during ExtensionMethodGenerator construction.","commonSituations":"See trigger scenarios.","solutions":["Add a first parameter of the base type the method extends","Add namespace = \"...\" to @TemplateExtension if the method belongs to a namespace rather than extending a type","Remove the annotation if the method is not meant as an extension method"],"exampleFix":"// before\n@TemplateExtension(matchName = \"double\")\nstatic int doubleIt() { return 2; }\n// after\n@TemplateExtension(matchName = \"double\")\nstatic int doubleIt(Integer val) { return val * 2; }","handlingStrategy":"validation","validationCode":"if (ext.namespace().isEmpty() && m.getParameterCount() == 0)\n    throw new IllegalStateException(\"Non-namespace extension needs a base object parameter: \" + m);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Every non-namespace extension's first parameter is the base type","Use namespace only for global functions","Check the method extends an actual template value type"],"tags":["qute","template-extension","signature","build-time"],"backgroundTag":"template-extension-signature-mismatch","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"}