quarkusio/quarkus · error · TemplateException
Invalid composite parameter found:
Error message
Invalid composite parameter found:
What it means
Qute parses composite (parenthesized) parameters inside {#if} sections, e.g. {#if (a || b) && c}. A composite param string starts with Parser.BEGIN_COMPOSITE_PARAM ('(') and must end with END_COMPOSITE_PARAM (')'). If the string ends with anything else, the parameter is structurally malformed and TemplateException is thrown during template parsing.
Source
Thrown at independent-projects/qute/core/src/main/java/io/quarkus/qute/IfSectionHelper.java:716
}
private static int getHighestPrecedence(List<Object> params) {
int highestPrecedence = 0;
for (Object param : params) {
if (param instanceof Operator) {
Operator op = (Operator) param;
if (op.precedence > highestPrecedence) {
highestPrecedence = op.precedence;
}
}
}
return highestPrecedence;
}
static <B extends ErrorInitializer & WithOrigin> List<Object> processCompositeParam(String stringParam, B block) {
// Composite params
if (!stringParam.endsWith("" + Parser.END_COMPOSITE_PARAM)) {
throw new TemplateException("Invalid composite parameter found: " + stringParam);
}
List<Object> split = new ArrayList<>();
Parser.splitSectionParams(stringParam.substring(1, stringParam.length() - 1),
block)
.forEachRemaining(split::add);
return parseParams(split, block);
}
@SuppressWarnings("unchecked")
static Condition createCondition(Object param, SectionBlock block, Operator operator, SectionInitContext context) {
Condition condition;
if (param instanceof String) {
String stringParam = param.toString();
boolean logicalComplement = stringParam.startsWith(LOGICAL_COMPLEMENT);
if (logicalComplement) {
stringParam = stringParam.substring(1);View on GitHub (pinned to e1c734241f)
Solutions
- Balance the parentheses in the {#if} condition so every '(' has a matching ')', e.g. {#if (a || b) && c}
- If the condition is complex, split it into nested {#if} sections instead of one deeply parenthesized expression
- Validate template syntax at build/startup (templates are parsed eagerly when possible) so the failure is caught before users hit the page
Example fix
// before
{#if (user.active || user.admin && debug}...{/if}
// after
{#if (user.active || user.admin) && debug}...{/if} Defensive patterns
Strategy: validation
Validate before calling
long opens = expr.chars().filter(c -> c == '(').count();
long closes = expr.chars().filter(c -> c == ')').count();
if (opens != closes) throw new IllegalArgumentException("Unbalanced parentheses in: " + expr); Try / catch
try {
engine.parse(content);
} catch (TemplateException e) {
if (e.getMessage().startsWith("Invalid composite parameter found")) {
throw new TemplateSyntaxException(content, "Unbalanced parentheses in {#if} expression", e);
}
throw e;
} Prevention
- Count '(' vs ')' before shipping template changes
- Split deeply nested conditions into nested {#if} sections
- Lint templates in CI by parsing all of them at build time
When it happens
Trigger: A parenthesized fragment inside an {#if} section whose closing parenthesis is missing or the param string is corrupted, e.g. {#if (a || b && c} — the leading '(' opens a composite param but there is no matching ')'.
Common situations: Hand-edited templates where a closing paren was deleted; nested conditions with miscounted parentheses; template copy/paste truncation.
Related errors
- Not a binary operator:
- Not a short-circuiting operator:
- Expression not found for param []:
- Unsupported param type:
- Template [" + templateId + "] is not parsed yet
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c0e52fb8aea126eb.
Report an issue: GitHub.