quarkusio/quarkus · error · RuntimeException
Invalid template link [${templateLink}] - Expeting a link th
Error message
Invalid template link [${templateLink}] - Expeting a link that ends with .html What it means
QuteDataPageBuilder.templateLink(String) validates that the Qute template link is a non-empty path ending in '.html' because the Dev UI resolves and serves the underlying Qute template file by that path. Anything else cannot be located or rendered.
Source
Thrown at extensions/devui/deployment-spi/src/main/java/io/quarkus/devui/spi/page/QuteDataPageBuilder.java:17
package io.quarkus.devui.spi.page;
public class QuteDataPageBuilder extends PageBuilder<QuteDataPageBuilder> {
private static final String DOT_HTML = ".html";
private static final String QWC_DATA_QUTE_PAGE_JS = "qwc-data-qute-page.js";
private String templateLink;
protected QuteDataPageBuilder(String title) {
super();
super.title = title;
super.internalComponent = true;// As external page runs on "internal" namespace
super.componentLink = QWC_DATA_QUTE_PAGE_JS;
}
public QuteDataPageBuilder templateLink(String templateLink) {
if (templateLink == null || templateLink.isEmpty() || !templateLink.endsWith(DOT_HTML)) {
throw new RuntimeException(
"Invalid template link [" + templateLink + "] - Expeting a link that ends with .html");
}
this.templateLink = templateLink;
return this;
}
@Override
public Page build() {
super.metadata("templatePath", getTemplatePath());
return super.build();
}
public String getTemplatePath() {
return "/dev-ui/" + this.templateLink;
}
View on GitHub (pinned to e1c734241f)
Solutions
- Append the extension: templateLink("templates/my-page.html")
- Reference templates that exist under META-INF/resources of the extension and end with .html
- Normalize the input: if (link != null && !link.endsWith(".html")) link = link + ".html"; before calling
- Verify the file is present in the built artifact (check target/classes / the extension jar)
Example fix
// before
quteDataPageBuilder().templateLink("templates/status"); // throws
// after
quteDataPageBuilder().templateLink("templates/status.html"); Defensive patterns
Strategy: validation
Validate before calling
if (link == null || link.isBlank() || !link.endsWith(".html")) {
throw new IllegalStateException("templateLink must be a non-empty path ending in .html: " + link);
} Type guard
boolean isValidTemplateLink(String l) {
return l != null && !l.isBlank() && l.toLowerCase().endsWith(".html");
} Try / catch
try {
quteDataPageBuilder().templateLink(link);
} catch (RuntimeException e) {
if (e.getMessage().contains("Expeting a link that ends with .html")) {
quteDataPageBuilder().templateLink(link + ".html");
} else throw e;
} Prevention
- Always pass paths ending in .html, never source .md/.qute files
- Normalize suffixes before calling: if (!link.endsWith(".html")) link += ".html"
- Verify the template ships under META-INF/resources in the built jar
- Keep template path constants in one place to avoid drift
When it happens
Trigger: Calling quteDataPageBuilder().templateLink("templates/foo") or templateLink("") / templateLink(null) — i.e. missing the .html extension or passing an empty value.
Common situations: Storing the template path in config without the extension; users pointing at Markdown/asciidoc source files instead of the compiled HTML; path built by string concatenation dropping the suffix; classpath resource actually missing so the suffix was 'fixed' by removing it.
Related errors
- You have to specify a key. This is the key the user will pre
- You have to specify a description. This is what the user wil
- You have to specify userMessage that will be send to AI, or
- Failed to locate 'artifact' or 'group-id' and 'artifact-id'
- className parameter is required
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e4bd61ace7c5a48a.
Report an issue: GitHub.