quarkusio/quarkus · error · IllegalArgumentException
Literal must not be null
Error message
Literal must not be null
What it means
ExpressionImpl.literal() builds a literal Qute expression from a string and throws this IllegalArgumentException when the literal string is null. The library treats a null literal as a programming error because a literal expression must carry at least the raw text it represents. The public entry point literal(id, literal) computes the value via LiteralSupport.getLiteralValue(literal), which itself requires a non-null input.
Source
Thrown at independent-projects/qute/core/src/main/java/io/quarkus/qute/ExpressionImpl.java:38
*/
static ExpressionImpl from(String value) {
if (value == null || value.isEmpty()) {
return EMPTY;
}
return Parser.parseExpression(ExpressionImpl::syntheticId, value, Scope.EMPTY, Parser.SYNTHETIC_ORIGIN);
}
static ExpressionImpl literalFrom(int id, String literal) {
if (literal == null || literal.isEmpty()) {
return EMPTY;
}
Object literalValue = LiteralSupport.getLiteralValue(literal);
return literal(id, literal, literalValue, Parser.SYNTHETIC_ORIGIN);
}
static ExpressionImpl literal(int id, String literal, Object value, Origin origin) {
if (literal == null) {
throw new IllegalArgumentException("Literal must not be null");
}
String typeInfo = null;
if (value != null) {
typeInfo = Expressions.typeInfoFrom(value.getClass().getName());
}
return new ExpressionImpl(id, null, List.of(new PartImpl(literal, typeInfo)), value, origin);
}
static Integer syntheticId() {
return -1;
}
private final int id;
private final String namespace;
private final List<Part> parts;
private final CompletedStage<Object> literal;
private final Origin origin;
View on GitHub (pinned to e1c734241f)
Solutions
- Check the literal string for null before calling literal()/literalFrom() and substitute an empty string or skip the expression.
- If the value is genuinely absent, build the expression with the value-only overload instead of a null literal text.
- Trace back where the null token came from — usually an upstream parse or lookup that produced null unexpectedly.
Example fix
// before
String text = maybeNull();
Expression e = ExpressionImpl.literal(1, text);
// after
String text = maybeNull();
if (text == null) {
text = ""; // or skip creating the expression
}
Expression e = ExpressionImpl.literal(1, text); Defensive patterns
Strategy: validation
Validate before calling
if (literalText == null) {
throw new IllegalArgumentException("literal text required");
}
Expression e = ExpressionImpl.literal(id, literalText); Type guard
boolean isValidLiteral(String s) { return s != null; } Try / catch
try {
Expression e = ExpressionImpl.literal(id, text);
} catch (IllegalArgumentException ex) {
// fall back to empty/synthetic expression
} Prevention
- Never pass possibly-null strings into expression builder APIs
- Coerce nulls to empty strings at the parse boundary
- Add a null check assertion in custom parser code before building literal expressions
When it happens
Trigger: Calling ExpressionImpl.literal(int id, String literal) or literalFrom(...) with a null literal argument, or passing null text derived from parsing (e.g. a parser/synthetic expression built with a null token).
Common situations: Custom template parsers or tooling that constructs synthetic literal expressions; passing a variable holding template text that was never initialized; reflection-based code building expressions where a token lookup returned null.
Related errors
- listener must not be null
- Index parameter is missing
- Invalid template link [${templateLink}] - Expeting a link th
- Contextual parameter must not be null
- Templates that are not backed by a file must provide extensi
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/cc358f4449bc3e74.
Report an issue: GitHub.