quarkusio/quarkus · error · RuntimeException
Missing @RoleValue annotation on (non-String) role element t
Error message
Missing @RoleValue annotation on (non-String) role element type: ${elementType} What it means
For a non-String role element type (e.g. List<RoleEntity>), the generator needs a member of the role class annotated with @RoleValue to know which field/method yields the role name string. If no such annotated member exists (or it is ambiguous/unresolvable), the build fails.
Source
Thrown at extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java:178
break;
case PARAMETERIZED_TYPE:
DotName roleType = rolesType.name();
if (roleType.equals(DotNames.LIST)
|| roleType.equals(DOTNAME_COLLECTION)
|| roleType.equals(DOTNAME_SET)) {
Type elementType = rolesType.asParameterizedType().arguments().get(0);
JpaSecurityDefinition.FieldOrMethod rolesFieldOrMethod;
if (!elementType.name().equals(DotNames.STRING)) {
ClassInfo roleClass = index.getClassByName(elementType.name());
if (roleClass == null) {
throw new RuntimeException(
"The role element type must be indexed by Jandex: " + elementType);
}
AnnotationTarget annotatedRolesValue = getSingleAnnotatedElement(index, DOTNAME_ROLES_VALUE);
rolesFieldOrMethod = JpaSecurityDefinition.getFieldOrMethod(index, roleClass,
annotatedRolesValue, panacheEntityPredicate.isPanache(roleClass));
if (rolesFieldOrMethod == null) {
throw new RuntimeException(
"Missing @RoleValue annotation on (non-String) role element type: " + elementType);
}
} else {
rolesFieldOrMethod = null;
}
// for(:elementType roleElement : :role){
// JpaIdentityProviderUtil.addRoles(:role.roleField);
// // or for String collections:
// JpaIdentityProviderUtil.addRoles(:role);
// }
bc.forEach(role, (loopBody, var) -> {
Expr roleElement;
if (rolesFieldOrMethod != null) {
roleElement = rolesFieldOrMethod.readValue(loopBody, var);
} else {
roleElement = var;
}
loopBody.invokeStatic(View on GitHub (pinned to e1c734241f)
Solutions
- Annotate exactly one field or getter of the role entity class with @RoleValue (e.g. the role name String).
- Alternatively, revert the @Roles field to a plain String or List<String>.
- Verify the @RoleValue annotation is io.quarkus.security.jpa.RolesValue and applied to a readable field/getter of the role class.
Example fix
// before
public class Role { private String name; }
// after
public class Role {
@RoleValue
public String getName() { return name; }
} Defensive patterns
Strategy: validation
Validate before calling
boolean hasRoleValue = Arrays.stream(Role.class.getDeclaredMethods())
.anyMatch(m -> m.isAnnotationPresent(RolesValue.class))
|| Arrays.stream(Role.class.getDeclaredFields())
.anyMatch(f -> f.isAnnotationPresent(RolesValue.class));
if (!hasRoleValue) throw new IllegalStateException("Role entity needs exactly one @RoleValue member"); Prevention
- Always add @RoleValue to the role-name getter when using entity-typed roles.
- Place @RoleValue on exactly one member of the role class.
- Keep role-name members public or getter-accessible.
When it happens
Trigger: Declaring @Roles on a List/Set/Collection of a custom role entity class that has no field or getter annotated with @io.quarkus.security.jpa.RolesValue.
Common situations: Role entity written without @RoleValue because roles were previously Strings and then refactored to an entity; annotation placed on the user entity instead of the role entity; @RoleValue accidentally on multiple members (which trips the sibling single-annotation error instead).
Related errors
- Unknown password type: ${passwordType}
- You can only annotate one field or method with @${annotation
- The role element type must be indexed by Jandex: ${elementTy
- Unsupported @Roles field/getter type: ${rolesType}
- You can only annotate one class with @UserDefinition
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/edc6d79a961ae0dc.
Report an issue: GitHub.