quarkusio/quarkus · error · io.quarkus.qute.TemplateException
Template record component [<name>] conflicts with an interfa
Error message
Template record component [<name>] conflicts with an interface method of <recordInterface>
What it means
When a template record implements (via its record interface) a @CheckedTemplate interface, Qute reserves the names of the interface's methods (plus template built-ins) for the interface bindings. A record component using one of these reserved names (e.g. 'toString', an interface method name like 'list', or built-in names such as 'inject'/'root') would clash at code-generation time, so collectCheckedTemplates fails the build.
Source
Thrown at extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java:497
+ recordClass.name());
} else {
throw new TemplateException(
startsWith + " match the path " + templatePath
+ " but the file suffix is not configured via the quarkus.qute.suffixes property");
}
}
Map<String, String> bindings = new HashMap<>();
List<Type> parameters = canonicalConstructor.parameterTypes();
for (int i = 0; i < parameters.size(); i++) {
Type type = parameters.get(i);
String name = canonicalConstructor.parameterName(i);
if (name == null) {
throw new TemplateException("Parameter names not recorded for " + recordClass.name()
+ ": compile the class with -parameters");
}
if (reservedNames.contains(name)) {
throw new TemplateException("Template record component [" + name
+ "] conflicts with an interface method of " + recordInterface);
}
bindings.put(name, getCheckedTemplateParameterTypeName(type));
}
AnnotationValue requireTypeSafeExpressions = checkedTemplateAnnotation != null
? checkedTemplateAnnotation.value(CHECKED_TEMPLATE_REQUIRE_TYPE_SAFE)
: null;
ret.add(new CheckedTemplateBuildItem(templatePath, fragmentId, bindings, null, recordClass,
requireTypeSafeExpressions != null ? requireTypeSafeExpressions.asBoolean() : true));
transformers.produce(new BytecodeTransformerBuildItem(recordClass.name().toString(),
new TemplateRecordEnhancer(recordInterface, recordClass, templatePath, fragmentId,
canonicalConstructor.descriptor(), canonicalConstructor.parameters(),
adaptors.get(recordInterfaceName))));
}
}
return ret;
}View on GitHub (pinned to e1c734241f)
Solutions
- Rename the record component (e.g. userName instead of name) and update the template placeholders accordingly
- Rename or remove the conflicting interface method if it's not needed
- Remove the redundant component if the value can come from the interface binding itself
Example fix
// before
record item(String list) implements Templates.Item {}
// after
record item(String listItems) implements Templates.Item {} // update template: {listItems} Defensive patterns
Strategy: validation
Validate before calling
// check record component names against interface methods
java.lang.reflect.RecordComponent[] comps = item.class.getRecordComponents();
Set<String> reserved = new HashSet<>();
for (Method m : Templates.Item.class.getMethods()) reserved.add(m.getName());
reserved.addAll(Set.of("inject","root","ort","cdi","noroot","noinject"));
for (RecordComponent rc : comps) {
if (reserved.contains(rc.getName())) {
throw new IllegalStateException("Reserved component name: " + rc.getName());
}
} Prevention
- Avoid naming record components like Qute built-ins (inject, root, cdi, ...) or like the interface's methods
- Prefix component names when in doubt (e.g. itemName)
- Update templates when renaming components
- Keep record interfaces minimal to shrink the reserved-name set
When it happens
Trigger: A record used as a template record has a component whose name equals an interface method of the checked-template interface it implements (checked against the reservedNames set built from recordInterface methods and Qute reserved names).
Common situations: Naming a record component 'name' or 'items' when the checked template interface declares a method with the same name; components mirroring built-in template keys; mechanical renames that collide with interface methods.
Related errors
- Parameter names not recorded for <recordClass>: compile the
- Message bundle name [%s] declared on %s must be a valid name
- Message bundle interface name conflict - [%s] is used for bo
- @MessageBundle must be declared on an interface: {bundleClas
- <startsWith> match the path <templatePath> but the file suff
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4151e32c1a5ffa38.
Report an issue: GitHub.