quarkusio/quarkus · error · TemplateException
Template extension method declared on must accept at least
Error message
Template extension method declared on must accept at least one string parameter to match the name:
What it means
An extension method that requires a name parameter (@TemplateExtension(matchNames/matchRegex/ANY, or namespace matching by name) must include a java.lang.String parameter that receives the matched name. Qute throws TemplateException in the constructor when isNameParameterRequired is set but no String NAME-kind parameter exists.
Source
Thrown at independent-projects/qute/generator/src/main/java/io/quarkus/qute/generator/ExtensionMethodGenerator.java:987
}
} else {
// No namespace but matches any or regex
params.add(new Param(method.parameterName(i), parameters.get(i), i, ParamKind.BASE));
}
} else if (indexed == 1 && !hasNamespace && isNameParameterRequired) {
indexed++;
params.add(new Param(method.parameterName(i), parameters.get(i), i, ParamKind.NAME));
} else {
indexed++;
params.add(new Param(method.parameterName(i), parameters.get(i), i, ParamKind.EVAL));
}
}
this.params = params;
if (isNameParameterRequired) {
Param nameParam = getFirst(ParamKind.NAME);
if (nameParam == null || !nameParam.type.name().equals(DotNames.STRING)) {
throw new TemplateException(
"Template extension method declared on " + method.declaringClass().name()
+ " must accept at least one string parameter to match the name: " + method);
}
}
if (!hasNamespace && getFirst(ParamKind.BASE) == null) {
throw new TemplateException(
"Template extension method declared on " + method.declaringClass().name()
+ " must accept at least one parameter to match the base object: " + method);
}
for (Param param : params) {
if (param.kind == ParamKind.ATTR && !param.type.name().equals(DotNames.OBJECT)) {
throw new TemplateException(
"Template extension method parameter annotated with @TemplateAttribute declared on "
+ method.declaringClass().name()
+ " must be of type java.lang.Object: " + method);
}
}View on GitHub (pinned to e1c734241f)
Solutions
- Add a java.lang.String parameter in the position expected for the name
- Change an existing name parameter's type to java.lang.String
- Remove matchNames/matchRegex/ANY and use a fixed matchName if the name parameter is unwanted
Example fix
// before
@TemplateExtension(matchNames = {"a", "b"})
static String get(Object base) { ... }
// after
@TemplateExtension(matchNames = {"a", "b"})
static String get(Object base, String name) { ... } Defensive patterns
Strategy: validation
Validate before calling
if ((ext.matchRegex().isPresent() || ext.matchNames().length > 0 || ext.matchName().equals(TemplateExtension.ANY))
&& Arrays.stream(m.getParameterTypes()).noneMatch(t -> t == String.class))
throw new IllegalStateException("Extension must accept a String name parameter: " + m); Prevention
- Use java.lang.String (not CharSequence) for name parameters
- Re-check signatures after changing matching strategy
- Write unit tests invoking multi-name extensions
When it happens
Trigger: Declaring @TemplateExtension(matchRegex=...) or ANY where the name parameter is missing or not java.lang.String (e.g. CharSequence, Object); detected when the ExtensionMethodGenerator is constructed.
Common situations: Using CharSequence for the name parameter; removing the name param while keeping matchRegex; copying a fixed-name extension and adding matchNames without adding the parameter.
Related errors
- A template extension method matching multiple names or a reg
- Template extension method declared on must accept at least
- Template extension method declared on must be static:
- Template extension method declared on must not return void:
- Template extension method declared on must not be private:
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4a65c78fc96bddcc.
Report an issue: GitHub.