quarkusio/quarkus · error · TemplateException

Incompatible checked template return type: {returnType} only

Error message

Incompatible checked template return type: {returnType} only {supportedAdaptors}

What it means

Methods annotated @CheckedTemplate must be static/native and return a supported adaptor type: TemplateInstance or a type with a registered CheckedTemplateAdapter. A non-TemplateInstance return type without a registered adapter causes this TemplateException.

Source

Thrown at extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java:365

        for (AnnotationInstance annotation : index.getIndex().getAnnotations(Names.CHECKED_TEMPLATE)) {
            if (annotation.target().kind() != Kind.CLASS) {
                continue;
            }
            ClassInfo targetClass = annotation.target().asClass();
            if (targetClass.isRecord()) {
                // Template records are processed separately
                continue;
            }
            NativeCheckedTemplateEnhancer enhancer = new NativeCheckedTemplateEnhancer();
            for (MethodInfo method : targetClass.methods()) {
                // only keep native static methods
                if (!Modifier.isStatic(method.flags())
                        || !Modifier.isNative(method.flags())) {
                    continue;
                }
                // check its return type
                if (method.returnType().kind() != Type.Kind.CLASS) {
                    throw new TemplateException("Incompatible checked template return type: " + method.returnType()
                            + " only " + supportedAdaptors);
                }
                DotName returnTypeName = method.returnType().asClassType().name();
                CheckedTemplateAdapter adaptor = null;
                // if it's not the default template instance, try to find an adapter
                if (!returnTypeName.equals(Names.TEMPLATE_INSTANCE)) {
                    adaptor = adaptors.get(returnTypeName);
                    if (adaptor == null)
                        throw new TemplateException("Incompatible checked template return type: " + method.returnType()
                                + " only " + supportedAdaptors);
                }
                String fragmentId = getCheckedFragmentId(method, annotation);
                String templatePath = getCheckedTemplatePath(index.getIndex(), annotation, fragmentId, targetClass, method);
                String fullPath = templatePath + (fragmentId != null ? "$" + fragmentId : "");
                AnnotationTarget checkedTemplate = checkedTemplates.putIfAbsent(fullPath, method);
                if (checkedTemplate != null) {
                    throw new TemplateException(
                            String.format(

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the method return type to TemplateInstance (or a supported type)
  2. Register a CheckedTemplateAdapterBuildItem for the custom return type in a deployment module
  3. Remove @CheckedTemplate if the method is not a checked template accessor

Example fix

// before
class Templates {
    @CheckedTemplate
    static native MyWrapper page(); // no adapter
}
// after
class Templates {
    @CheckedTemplate
    static native TemplateInstance page();
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure all @CheckedTemplate methods return TemplateInstance
for (Method m : Templates.class.getDeclaredMethods()) {
    if (m.isAnnotationPresent(CheckedTemplate.class)
        && !TemplateInstance.class.isAssignableFrom(m.getReturnType()))
        throw new IllegalStateException(m + " must return TemplateInstance");
}

Type guard

static boolean isValidCheckedTemplate(Method m) {
    return TemplateInstance.class.equals(m.getReturnType());
}

Prevention

When it happens

Trigger: A @CheckedTemplate method declares a return type that is neither TemplateInstance nor a registered adapted type (e.g. a custom wrapper without registering an adapter).

Common situations: Upgrading Quarkus where adaptor registration requirements changed; custom template wrapper classes used with @CheckedTemplate; forgetting to register an adapter build item for a custom type.

Related errors


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