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
- Keep exactly one @RestLinkId field in the entity hierarchy; remove it from the other field(s).
- Alternatively annotate a different existing field with @Id or name it `id` and drop the extra @RestLinkId.
- 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
- One identifier annotation per class hierarchy
- Audit inherited fields before adding @RestLinkId
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
- Cannot generate web links for the class because it is eithe
- The @Blocking, @NonBlocking and @RunOnVirtualThread annotati
- Value not set for ${param}
- TransformedAnnotationsBuildItem#queryForMethodParam needs to
- @Compressed and @Uncompressed cannot be both declared on res
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/521429d94eb8e644.
Report an issue: GitHub.