quarkusio/quarkus · error · PanacheQueryException
The annotation ProjectedFieldName must have a non-empty valu
Error message
The annotation ProjectedFieldName must have a non-empty value.
What it means
getNameFromProjectedFieldName reads the value() member of a @ProjectedFieldName-style annotation found on a constructor parameter. If the annotation is present but its value is the empty string, Panache throws PanacheQueryException because an empty name cannot be mapped to any select item. This is a direct misuse of the annotation's contract that value must be a non-empty field name.
Source
Thrown at extensions/panache/panache-hibernate-common/runtime/src/main/java/io/quarkus/panache/hibernate/common/runtime/ProjectionConstructorUtil.java:208
return false;
}
private static boolean hasAnnotation(AnnotatedElement annotatedElement, String annotationTypeName) {
for (java.lang.annotation.Annotation annotation : annotatedElement.getAnnotations()) {
if (annotationTypeName.equals(annotation.annotationType().getName())) {
return true;
}
}
return false;
}
private static String getNameFromProjectedFieldName(AnnotatedElement annotatedElement) {
for (java.lang.annotation.Annotation annotation : annotatedElement.getAnnotations()) {
if (PROJECTED_FIELD_NAME_ANNOTATIONS.contains(annotation.annotationType().getName())) {
try {
String name = (String) annotation.annotationType().getMethod("value").invoke(annotation);
if (name.isEmpty()) {
throw new PanacheQueryException("The annotation ProjectedFieldName must have a non-empty value.");
}
return name;
} catch (ReflectiveOperationException e) {
throw new PanacheQueryException("Unable to read ProjectedFieldName value", e);
}
}
}
throw new PanacheQueryException("Missing ProjectedFieldName annotation");
}
private static String buildNoSuitableConstructorMessage(Class<?> type, Constructor<?> rejected) {
StringBuilder message = new StringBuilder("No suitable projection constructor found for ")
.append(type.getName())
.append(" (rejected constructor: ")
.append(rejected)
.append(").");
if (isKotlinClass(type)) {
message.append(" Kotlin value classes and default parameters may produce synthetic constructors.")View on GitHub (pinned to e1c734241f)
Solutions
- Set the annotation value to the actual select item/attribute name: @ProjectedFieldName("fullName")
- If the parameter name already matches, remove the annotation entirely so the compiler-provided name is used
- Add validation on dynamically generated DTOs to assert annotation values are non-empty
Example fix
// before
public PersonDto(@ProjectedFieldName("") String name) { ... }
// after
public PersonDto(@ProjectedFieldName("name") String name) { ... } Defensive patterns
Strategy: validation
Validate before calling
static void assertProjectedFieldNameNonEmpty(java.lang.reflect.Parameter p) {
ProjectedFieldName a = p.getAnnotation(ProjectedFieldName.class);
if (a != null && a.value().isEmpty()) {
throw new IllegalStateException("@ProjectedFieldName on " + p + " must be non-empty");
}
} Try / catch
try {
return query.project(Dto.class).list();
} catch (PanacheQueryException e) {
if (e.getMessage().contains("non-empty value")) {
throw new IllegalStateException("Fix empty @ProjectedFieldName values on " + Dto.class, e);
}
throw e;
} Prevention
- Never leave @ProjectedFieldName("") placeholders; fill in the attribute name immediately
- If the parameter name already matches the field, omit the annotation rather than using an empty value
- Code-review DTO constructors for annotation completeness
- Add an ArchUnit/startup check validating annotation values on projection DTOs
When it happens
Trigger: Declaring @ProjectedFieldName("") (or an aliased annotation whose value resolves to "") on a projection constructor parameter, then running a query that triggers projection construction.
Common situations: Placeholder left from code generation; programmatically built annotation values from config that resolved to empty; copy-paste where the value was deleted accidentally.
Related errors
- Unable to read ProjectedFieldName value
- Missing ProjectedFieldName annotation
- The named query '${namedQuery}' must be defined on your JPA
- Query string cannot be empty
- Sort column name cannot have backticks
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/fa19016171a6ffb3.
Report an issue: GitHub.