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
- Register the resolver via EngineBuilder.addNamespaceResolver(...) so the engine sets the engine reference during build, then only evaluate templates after build() returns.
- Never resolve str: expressions from within engine construction callbacks or static initializers.
- 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
- Always register StrEvalNamespaceResolver via EngineBuilder, never instantiate-and-use standalone
- Never evaluate templates during engine construction
- Gate resolution code behind an 'engine ready' flag set after build()
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
- Services have not been started yet
- No template variant found
- OIDC Client Registration is closed
- Registered OIDC Client is closed
- RestClientProxy is closed
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/61371eaad4c4ad62.
Report an issue: GitHub.