{"record":{"id":"e97cf72cc513edaf","repo":"quarkusio/quarkus","slug":"reflection-invocation-error-e97cf7","errorCode":null,"errorMessage":"Reflection invocation error","messagePattern":"Reflection invocation error","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"independent-projects/qute/core/src/main/java/io/quarkus/qute/GetterAccessor.java","lineNumber":23,"sourceCode":"\n/**\n *\n * @see ReflectionValueResolver\n */\nclass GetterAccessor implements ValueAccessor, AccessorCandidate {\n\n    private final Method method;\n\n    GetterAccessor(Method method) {\n        this.method = method;\n    }\n\n    @Override\n    public CompletionStage<Object> getValue(Object instance) {\n        try {\n            return CompletionStageSupport.toCompletionStage(method.invoke(instance));\n        } catch (Exception e) {\n            throw new IllegalStateException(\"Reflection invocation error\", e);\n        }\n    }\n\n    @Override\n    public ValueAccessor getAccessor(EvalContext context) {\n        return this;\n    }\n\n}\n","sourceCodeStart":5,"sourceCodeEnd":33,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/qute/core/src/main/java/io/quarkus/qute/GetterAccessor.java#L5-L33","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npublic String getName() { return config.missing().name(); } // throws inside getter\n// after\npublic String getName() {\n    return config != null && config.missing() != null ? config.missing().name() : null;\n}","handlingStrategy":"try-catch","validationCode":"Method m = instance.getClass().getMethod(\"getName\");\nif (instance == null) { /* guard before invoking getter */ }","typeGuard":"boolean canInvoke(Object instance, String getter) {\n    if (instance == null) return false;\n    try { instance.getClass().getMethod(getter); return true; }\n    catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n    return accessor.getValue(instance).toCompletableFuture().join();\n} catch (IllegalStateException ex) {\n    Throwable cause = ex.getCause(); // real error from the getter\n    LOGGER.warnf(cause, \"getter invocation failed on %s\", instance);\n    throw ex;\n}","preventionTips":["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"],"tags":["qute","reflection","native-image","getter"],"backgroundTag":"reflection-invocation-failed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}