quarkusio/quarkus · error · IllegalStateException

Cannot generate web links for the class because it has mult

Error message

Cannot generate web links for the class  because it has multiple fields annotated with `@RestLinkId`, where a maximum of one is allowed

What it means

rest-links requires exactly one identifier per entity class so it can build a link path parameter. validateRec throws IllegalStateException when an entity has more than one field annotated with @RestLinkId, since the link id would be ambiguous.

Source

Thrown at extensions/resteasy-reactive/rest-links/deployment/src/main/java/io/quarkus/resteasy/reactive/links/deployment/LinksProcessor.java:256

     * @throws IllegalStateException if the classname does not contain any sort of field identifier
     */
    private void validateRec(IndexView index, String entityType, ClassInfo classInfo) {
        List<FieldInfo> fieldsNamedId = classInfo.fields().stream()
                .filter(f -> f.name().equals("id"))
                .toList();

        List<AnnotationInstance> fieldsAnnotatedWithId = classInfo.fields().stream()
                .flatMap(f -> f.annotations().stream())
                .filter(a -> a.name().toString().endsWith("persistence.Id"))
                .toList();

        List<AnnotationInstance> fieldsAnnotatedWithRestLinkId = classInfo.fields().stream()
                .flatMap(f -> f.annotations(RestLinkId.class).stream())
                .toList();

        // @RestLinkId annotation count > 1 is not allowed
        if (fieldsAnnotatedWithRestLinkId.size() > 1) {
            throw new IllegalStateException("Cannot generate web links for the class " + entityType +
                    " because it has multiple fields annotated with `@RestLinkId`, where a maximum of one is allowed");
        }

        // Id field found, break the loop
        if (!fieldsNamedId.isEmpty() || !fieldsAnnotatedWithId.isEmpty() || !fieldsAnnotatedWithRestLinkId.isEmpty()) {
            return;
        }

        // Id field not found and hope is gone
        DotName superClassName = classInfo.superName();
        if (superClassName == null) {
            throw new IllegalStateException("Cannot generate web links for the class " + entityType +
                    " because it is either missing an `id` field, a field with an `@Id` annotation or a field with a `@RestLinkId annotation");
        }

        // Id field not found but there's still hope
        classInfo = index.getClassByName(superClassName);
        if (classInfo == null) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Keep exactly one @RestLinkId field in the entity hierarchy; remove it from the other field(s).
  2. Alternatively annotate a different existing field with @Id or name it `id` and drop the extra @RestLinkId.
  3. Re-run the build to confirm only one id source is detected.

Example fix

// before
class User { @RestLinkId var id: Long; @RestLinkId var username: String }
// after
class User { @RestLinkId var id: Long; var username: String }
Defensive patterns

Strategy: validation

Validate before calling

val ids = entityClass.declaredFields.count { it.isAnnotationPresent(RestLinkId::class.java) }
check(ids <= 1) { "@RestLinkId must appear at most once per hierarchy" }

Prevention

When it happens

Trigger: Annotating two or more fields of the same entity (or the same class in its hierarchy) with @RestLinkId; e.g. adding @RestLinkId to a new field while a base class already has one.

Common situations: Refactoring entities with inheritance; copy-pasting the annotation onto multiple id-like fields (id, uuid, code).

Related errors


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