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

  1. Check the literal string for null before calling literal()/literalFrom() and substitute an empty string or skip the expression.
  2. If the value is genuinely absent, build the expression with the value-only overload instead of a null literal text.
  3. 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

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


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