{"record":{"id":"fb7437ff956e1a02","repo":"quarkusio/quarkus","slug":"no-template-variant-found","errorCode":null,"errorMessage":"No template variant found","messagePattern":"No template variant found","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MailTemplateInstanceImpl.java","lineNumber":159,"sourceCode":"                                                    .setAttribute(TemplateInstance.SELECTED_VARIANT, variant).renderAsync();\n                                        }\n                                    })));\n                }\n            }\n            if (results.isEmpty()) {\n                throw new IllegalStateException(\"No suitable template variant found\");\n            }\n            List<Uni<String>> unis = results.stream().map(Result::resolve).collect(Collectors.toList());\n            return Uni.combine().all().unis(unis)\n                    .combinedWith(combine(results))\n                    .chain(new Function<Mail, Uni<? extends Void>>() {\n                        @Override\n                        public Uni<? extends Void> apply(Mail m) {\n                            return mailer.send(m);\n                        }\n                    });\n        } else {\n            throw new IllegalStateException(\"No template variant found\");\n        }\n    }\n\n    private Function<List<?>, Mail> combine(List<Result> results) {\n        return new Function<List<?>, Mail>() {\n            @Override\n            public Mail apply(List<?> resolved) {\n                for (int i = 0; i < resolved.size(); i++) {\n                    Result result = results.get(i);\n                    // We can safely cast, as we know that the results are Strings.\n                    String content = (String) resolved.get(i);\n                    if (result.variant.getContentType().equals(Variant.TEXT_HTML)) {\n                        mail.setHtml(content);\n                    } else if (result.variant.getContentType().equals(Variant.TEXT_PLAIN)) {\n                        mail.setText(content);\n                    }\n                }\n                return mail;","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MailTemplateInstanceImpl.java#L141-L177","documentation":"MailTemplateInstanceImpl.send() renders a Qute template and mails the result. When the underlying Qute TemplateInstance exposes no TemplateInstance.VARIANTS attribute, send() cannot know which variants (text/html, text/plain) to render, so it throws this IllegalStateException. This happens when the injected MailTemplate does not come from a Qute template with multiple declared variants.","triggerScenarios":"Calling send() on a MailTemplateInstance whose Qute template was not loaded with template variants (e.g. the template defines no .qute.html/.qute.txt variant files, or the TemplateInstance was created programmatically without setting the VARIANTS attribute).","commonSituations":"Injecting a MailTemplate via @Location pointing to a plain template that only has a single non-variant file; using a custom TemplateInstance built by hand (e.g. via MailTemplateInstanceAdaptor) without variants; renaming template files so the html/txt variant suffixes no longer match.","solutions":["Ensure the template directory contains variant files with proper suffixes, e.g. templates/welcome.qute.html and templates/welcome.qute.txt, matching the @Location value.","If building a TemplateInstance programmatically, set instance.setAttribute(TemplateInstance.VARIANTS, List.of(variant...)) before calling send().","If you only need a fixed body, skip the mail template and use ReactiveMailer directly: mailer.send(Mail.withText(to, subject, body)).","Verify @Location(\"...\") path matches the actual resource under src/main/resources/templates."],"exampleFix":"// before (single non-variant template)\n@Inject @Location(\"welcome\") MailTemplate welcome; // templates/welcome.qute only\nwelcome.to(to).subject(sub).send();\n\n// after (variant files)\n// src/main/resources/templates/welcome.qute.html\n// src/main/resources/templates/welcome.qute.txt\nwelcome.to(to).subject(sub).send();","handlingStrategy":"validation","validationCode":"Object variants = templateInstance.templateInstance().getAttribute(TemplateInstance.VARIANTS);\nif (variants == null) {\n    throw new IllegalStateException(\"Template has no variants; add .qute.html/.qute.txt files or set the VARIANTS attribute\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    template.send().await().indefinitely();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"No template variant\")) {\n        LOG.error(\"Mail template lacks text/html or text/plain variants\", e);\n    }\n    throw e;\n}","preventionTips":["Always ship both welcome.qute.html and welcome.qute.txt variant files next to each other","Never build TemplateInstance objects manually unless you set TemplateInstance.VARIANTS","Add an application-startup smoke test that renders each mail template"],"tags":["quarkus","mailer","qute","template-variants","illegal-state"],"backgroundTag":"template-variant-not-found","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"}