{"record":{"id":"16d1632db25d0964","repo":"quarkusio/quarkus","slug":"unable-to-read-projectedfieldname-value","errorCode":null,"errorMessage":"Unable to read ProjectedFieldName value","messagePattern":"Unable to read ProjectedFieldName value","errorType":"exception","errorClass":"PanacheQueryException","httpStatus":null,"severity":"error","filePath":"extensions/panache/panache-hibernate-common/runtime/src/main/java/io/quarkus/panache/hibernate/common/runtime/ProjectionConstructorUtil.java","lineNumber":212,"sourceCode":"        for (java.lang.annotation.Annotation annotation : annotatedElement.getAnnotations()) {\n            if (annotationTypeName.equals(annotation.annotationType().getName())) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private static String getNameFromProjectedFieldName(AnnotatedElement annotatedElement) {\n        for (java.lang.annotation.Annotation annotation : annotatedElement.getAnnotations()) {\n            if (PROJECTED_FIELD_NAME_ANNOTATIONS.contains(annotation.annotationType().getName())) {\n                try {\n                    String name = (String) annotation.annotationType().getMethod(\"value\").invoke(annotation);\n                    if (name.isEmpty()) {\n                        throw new PanacheQueryException(\"The annotation ProjectedFieldName must have a non-empty value.\");\n                    }\n                    return name;\n                } catch (ReflectiveOperationException e) {\n                    throw new PanacheQueryException(\"Unable to read ProjectedFieldName value\", e);\n                }\n            }\n        }\n        throw new PanacheQueryException(\"Missing ProjectedFieldName annotation\");\n    }\n\n    private static String buildNoSuitableConstructorMessage(Class<?> type, Constructor<?> rejected) {\n        StringBuilder message = new StringBuilder(\"No suitable projection constructor found for \")\n                .append(type.getName())\n                .append(\" (rejected constructor: \")\n                .append(rejected)\n                .append(\").\");\n        if (isKotlinClass(type)) {\n            message.append(\" Kotlin value classes and default parameters may produce synthetic constructors.\")\n                    .append(\" Use @ProjectedConstructor, @ProjectedFieldName, or a DTO with plain property types such as Long.\");\n        } else {\n            message.append(\" Use @ProjectedConstructor or @ProjectedFieldName to select a usable constructor,\")\n                    .append(\" and ensure the application is built with parameter names (-parameters).\");","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/panache/panache-hibernate-common/runtime/src/main/java/io/quarkus/panache/hibernate/common/runtime/ProjectionConstructorUtil.java#L194-L230","documentation":"getNameFromProjectedFieldName invokes the annotation's value() method reflectively; any ReflectiveOperationException (missing value method, inaccessible method, InvocationTargetException) is wrapped and rethrown as PanacheQueryException(\"Unable to read ProjectedFieldName value\", e). Panache expects the annotation to follow the standard single String value() shape.","triggerScenarios":"Using an annotation matching a PROJECTED_FIELD_NAME_ANNOTATIONS name whose value() method is absent, non-String-returning, not accessible, or throws when invoked (e.g. a custom annotation with Class or array value).","commonSituations":"Custom meta-annotation mimicking ProjectedFieldName but with a different attribute signature; annotation on a class loaded by a restricted classloader in native mode; exotic annotation types with non-standard members.","solutions":["Use the standard io.quarkus.runtime.annotations.ProjectedFieldName annotation with a String value()","If using a custom annotation, ensure it declares public String value()","Check the cause (getCause) of the PanacheQueryException for the underlying reflective error","Avoid custom annotation indirection on projection constructors"],"exampleFix":"// before\npublic @interface FieldName { String name(); } // no value() method\n\n// after\npublic @interface FieldName { String value(); }","handlingStrategy":"try-catch","validationCode":"for (java.lang.annotation.Annotation a : param.getAnnotations()) {\n    try {\n        a.annotationType().getMethod(\"value\");\n    } catch (NoSuchMethodException e) {\n        throw new IllegalStateException(\"Annotation \" + a + \" lacks a value() method\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return query.project(Dto.class).list();\n} catch (PanacheQueryException e) {\n    if (e.getMessage().equals(\"Unable to read ProjectedFieldName value\") && e.getCause() != null) {\n        log.error(\"Bad annotation shape: {}\", e.getCause().toString());\n    }\n    throw e;\n}","preventionTips":["Use io.quarkus.runtime.annotations.ProjectedFieldName rather than custom look-alikes","If defining a custom annotation, keep the standard public String value() member","Inspect getCause() when this wraps an InvocationTargetException","Test projection queries in JVM tests to catch annotation problems early"],"tags":["panache","jpa","reflection","annotation","projection"],"backgroundTag":"reflective-annotation-read-failure","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"}