quarkusio/quarkus · error · IllegalStateException
bean has an @Identifier annotation with an empty value
Error message
bean has an @Identifier annotation with an empty value
What it means
Thrown by SignalsProcessor.readIdentifier when the @Identifier qualifier found on a signals component bean carries an empty string value. The processor uses the qualifier value as the bean's identifier for topological sorting of signal components; an empty identifier cannot key the idToBeans map, so the guard aborts the build naming the component type and bean. The message's leading placeholder is the componentTypeName prefixed at throw time.
Source
Thrown at extensions/signals/deployment/src/main/java/io/quarkus/signals/deployment/SignalsProcessor.java:430
if (idToBeans.keySet().isEmpty()) {
return List.of();
}
return TopologicalSort.sort(idToBeans.keySet(), beforeEdges, afterEdges, componentTypeName);
}
private static String readIdentifier(BeanInfo bean, String componentTypeName) {
if (bean.getTarget().isEmpty()) {
throw new IllegalStateException(componentTypeName + " bean has no target: " + bean);
}
Optional<AnnotationInstance> identifier = bean.getQualifier(DotNames.IDENTIFIER);
if (identifier.isEmpty()) {
throw new IllegalStateException(
componentTypeName + " bean " + bean.getBeanClass()
+ " must be annotated with @io.smallrye.common.annotation.Identifier");
}
AnnotationValue value = identifier.get().value();
if (value == null || value.asString().isBlank()) {
throw new IllegalStateException(
componentTypeName + " bean " + bean.getBeanClass()
+ " has an @Identifier annotation with an empty value");
}
return value.asString();
}
@BuildStep
ReceiverExecutorImplementationBuildItem supportedExecutionModels(Capabilities capabilities) {
if (capabilities.isPresent(Capability.VERTX)) {
return new ReceiverExecutorImplementationBuildItem(VERTX);
} else {
// Note that quarkus-virtual-threads does require quarkus-vertx,
// although it does not depend on the extension directly (to avoid the cycle)
return new ReceiverExecutorImplementationBuildItem(DEFAULT_BLOCKING);
}
}
@BuildStepView on GitHub (pinned to e1c734241f)
Solutions
- Provide a non-blank value: @Identifier("my-enricher").
- Check the constant/expression feeding the annotation value — it must be a compile-time non-blank string.
- Ensure each component gets a unique, meaningful id.
Example fix
// before
@Identifier("")
class MyEnricher implements Enricher { ... }
// after
@Identifier("my-enricher")
class MyEnricher implements Enricher { ... } Defensive patterns
Strategy: validation
Validate before calling
Identifier id = componentClass.getAnnotation(Identifier.class);
if (id == null || id.value().isBlank()) { throw new IllegalStateException("@Identifier must have a non-blank value on " + componentClass); } Prevention
- Never leave @Identifier's value empty or blank.
- Avoid empty constants in annotation values; use literal ids.
- Add a startup unit test validating all @Identifier values.
When it happens
Trigger: Using @Identifier with no value (e.g. @Identifier where the annotation's value member is empty) on an enricher/interceptor bean, or @Identifier("") / @Identifier(" ").
Common situations: Typing @Identifier and forgetting the value, or passing an externalized/empty constant.
Related errors
- Multiple beans with the same @Identifier value detected: ;
- bean must be annotated with @io.smallrye.common.annotation
- A context class must be a public non-abstract top-level or s
- name cannot be null
- Either location or predicate must be set
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/ab9aeb317e29e00f.
Report an issue: GitHub.