quarkusio/quarkus · error · IllegalStateException

Engine not set

Error message

Engine not set

What it means

StrEvalNamespaceResolver's str: namespace parses strings as templates, but it only has an Engine reference after being initialized by the engine builder. Calling parse before initialization throws IllegalStateException("Engine not set").

Source

Thrown at independent-projects/qute/core/src/main/java/io/quarkus/qute/StrEvalNamespaceResolver.java:81

            });
        }
        return ret;
    }

    @Override
    public int getPriority() {
        return priority;
    }

    @Override
    public String getNamespace() {
        return "str";
    }

    private Template parse(String contents, Variant variant) {
        Engine e = engine;
        if (e == null) {
            throw new IllegalStateException("Engine not set");
        }
        return e.parse(contents, variant);
    }

    private void resolve(CompletableFuture<Object> ret, EvalContext context, Template template) {
        template.getRootNode().resolve(context.resolutionContext()).whenComplete((r, t) -> {
            if (t != null) {
                ret.completeExceptionally(t);
            } else {
                StringBuilder sb = new StringBuilder();
                r.process(sb::append);
                ret.complete(new RawString(sb.toString()));
            }
        });
    }

}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Register the resolver via EngineBuilder.addNamespaceResolver(...) so the engine sets the engine reference during build, then only evaluate templates after build() returns.
  2. Never resolve str: expressions from within engine construction callbacks or static initializers.
  3. If using the resolver manually, ensure the EngineBuilder.build() has completed and assigned the engine before any resolution.

Example fix

// before
Engine engine = Engine.builder().build();
new StrEvalNamespaceResolver().parse("..."); // engine never injected

// after
Engine engine = Engine.builder()
        .addNamespaceResolver(new StrEvalNamespaceResolver())
        .build(); // resolver initialized, str: works
engine.parse("...");
Defensive patterns

Strategy: try-catch

Validate before calling

// resolve str: expressions only after EngineBuilder.build() has returned
Engine engine = builder.addNamespaceResolver(new StrEvalNamespaceResolver()).build();

Try / catch

try {
    Object value = evaluateTemplate(template);
} catch (IllegalStateException e) {
    if ("Engine not set".equals(e.getMessage())) {
        // defer evaluation until the engine is built/initialized
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Resolving a str: expression (e.g. {str:'...'} or nested evaluation) before the resolver was added to an Engine and the engine injected back — e.g. using the resolver standalone, or resolving during engine construction.

Common situations: Using StrEvalNamespaceResolver outside a fully built Engine (manual instantiation without EngineBuilder.addNamespaceResolver); calling template evaluation inside a build/initialization callback before EngineBuilder.build() completes.

Related errors


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