quarkusio/quarkus · error · RuntimeException

Unsupported @Roles field/getter type: ${rolesType}

Error message

Unsupported @Roles field/getter type: ${rolesType}

What it means

The @Roles field/getter type must be String, List<X>, Collection<X>, or Set<X>. Arrays and any other type kind (primitive, other classes, wildcard types, etc.) are not supported by the build-time role handler, so the build fails.

Source

Thrown at extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java:206

                    // }
                    bc.forEach(role, (loopBody, var) -> {
                        Expr roleElement;
                        if (rolesFieldOrMethod != null) {
                            roleElement = rolesFieldOrMethod.readValue(loopBody, var);
                        } else {
                            roleElement = var;
                        }
                        loopBody.invokeStatic(
                                MethodDesc.of(JpaIdentityProviderUtil.class, "addRoles", void.class,
                                        QuarkusSecurityIdentity.Builder.class, String.class),
                                builderVar, roleElement);
                    });
                    handledRole = true;
                }
                break;
        }
        if (!handledRole) {
            throw new RuntimeException("Unsupported @Roles field/getter type: " + rolesType);
        }

        // return builder.build()
        bc.return_(bc.invokeVirtual(
                MethodDesc.of(QuarkusSecurityIdentity.Builder.class,
                        "build",
                        QuarkusSecurityIdentity.class),
                builderVar));
    }

    private static MethodDesc getUtilMethod(String passwordProviderMethod) {
        return MethodDesc.of(JpaIdentityProviderUtil.class, passwordProviderMethod,
                Password.class, String.class);
    }

    private static MethodDesc passwordActionMethod() {
        return MethodDesc.of(JpaIdentityProviderUtil.class, "passwordAction", void.class, PasswordType.class);
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the @Roles field/getter type to String, List<String>, Set<String>, or Collection<String>.
  2. If roles are entities, use List<RoleEntity>/Set<RoleEntity> with a @RoleValue on the role class.
  3. If using a generic collection, always supply type parameters (e.g. List<String>, not raw List).
  4. Convert arrays (String[]) to List via entity mapping or change the JPA mapping to @ElementCollection.

Example fix

// before
@Roles
public String[] roles;

// after
@Roles
@ElementCollection
public List<String> roles;
Defensive patterns

Strategy: validation

Validate before calling

Class<?> t = rolesField.getType();
boolean ok = t == String.class || List.class.isAssignableFrom(t)
        || Set.class.isAssignableFrom(t) || Collection.class.isAssignableFrom(t);
if (!ok) throw new IllegalStateException("@Roles must be String or List/Set/Collection");

Prevention

When it happens

Trigger: Annotating a field/getter with @Roles whose declared type is String[], an array of entities, a Map, a raw/non-parameterized generic type (whose kind is CLASS but not String), or any other unsupported type.

Common situations: Using String[] roles from legacy code; using a raw List without type parameters (element type unknown -> handledRole stays false); using Optional<List<String>> or custom collection types not in the supported trio.

Related errors


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