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

  1. Add a java.lang.String parameter in the position expected for the name
  2. Change an existing name parameter's type to java.lang.String
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/4a65c78fc96bddcc. Report an issue: GitHub.