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

  1. Check the cause (e.getCause()) to find the real exception thrown inside the getter.
  2. Register the class for reflection for native mode (@RegisterForReflection / reflect-config.json).
  3. Fix or guard the getter so it does not throw for the evaluated value.
  4. 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

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


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