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);
        }
    }

    @BuildStep

View on GitHub (pinned to e1c734241f)

Solutions

  1. Provide a non-blank value: @Identifier("my-enricher").
  2. Check the constant/expression feeding the annotation value — it must be a compile-time non-blank string.
  3. 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

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


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