quarkusio/quarkus · error · IllegalStateException
Reflection invocation error
Error message
Reflection invocation error
What it means
GetterAccessor.getValue() invokes a getter method reflectively (method.invoke(instance)) and wraps any failure — IllegalAccessException, InvocationTargetException, NPE on null instance, wrong receiver type — in IllegalStateException("Reflection invocation error"). It is the reflection fallback for property resolution.
Source
Thrown at independent-projects/qute/core/src/main/java/io/quarkus/qute/GetterAccessor.java:23
/**
*
* @see ReflectionValueResolver
*/
class GetterAccessor implements ValueAccessor, AccessorCandidate {
private final Method method;
GetterAccessor(Method method) {
this.method = method;
}
@Override
public CompletionStage<Object> getValue(Object instance) {
try {
return CompletionStageSupport.toCompletionStage(method.invoke(instance));
} catch (Exception e) {
throw new IllegalStateException("Reflection invocation error", e);
}
}
@Override
public ValueAccessor getAccessor(EvalContext context) {
return this;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Check the cause (e.getCause()) to find the real exception thrown inside the getter.
- Register the class for reflection for native mode (@RegisterForReflection / reflect-config.json).
- Fix or guard the getter so it does not throw for the evaluated value.
- Restart cleanly in dev mode so cached reflective accessors are rebuilt.
Example fix
// before
public String getName() { return config.missing().name(); } // throws inside getter
// after
public String getName() {
return config != null && config.missing() != null ? config.missing().name() : null;
} Defensive patterns
Strategy: try-catch
Validate before calling
Method m = instance.getClass().getMethod("getName");
if (instance == null) { /* guard before invoking getter */ } Type guard
boolean canInvoke(Object instance, String getter) {
if (instance == null) return false;
try { instance.getClass().getMethod(getter); return true; }
catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
return accessor.getValue(instance).toCompletableFuture().join();
} catch (IllegalStateException ex) {
Throwable cause = ex.getCause(); // real error from the getter
LOGGER.warnf(cause, "getter invocation failed on %s", instance);
throw ex;
} Prevention
- Make getters null-safe for values rendered in templates
- Inspect ex.getCause() — the IllegalStateException wraps the real InvocationTargetException
- Register beans for reflection in native mode
- Avoid letting business exceptions escape getters used by templates
When it happens
Trigger: Resolving a property when no generated accessor exists and the underlying getter throws, is not accessible, the instance is null, or class redefinition (dev mode) invalidated the cached Method.
Common situations: Getter itself throwing a business exception that surfaces wrapped; native image missing reflection registration; dev-mode hot reload; resolving a getter on a mismatched object type.
Related errors
- Reflection invocation error
- Unable to find handleRequest method in <handlerClass.getName
- Unable to create new instance for ${clazz}
- Unable to load class [<className>]
- Unable to determine the name of the parameter at position {p
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e97cf72cc513edaf.
Report an issue: GitHub.