quarkusio/quarkus · error · IllegalStateException
Invalid type:
Error message
Invalid type:
What it means
The @CachedResults annotation target resolved to a Jandex Type whose kind is not CLASS (e.g. parameterized type, array, primitive, type variable). The generated cache-result producer needs a concrete class/interface name to index, so non-class types are rejected at build time.
Source
Thrown at extensions/cache/deployment/src/main/java/io/quarkus/cache/deployment/CachedResultsProcessor.java:348
AnnotationValue keyGeneratorValue = annotation.value("keyGenerator");
if (keyGeneratorValue != null)
keyGenerator = keyGeneratorValue.asClass().name();
AnnotationValue excludeValue = annotation.value("exclude");
if (excludeValue != null)
exclude = excludeValue.asString();
if (annotation.target().kind() == Kind.FIELD) {
type = annotation.target().asField().type();
} else if (annotation.target().kind() == Kind.METHOD_PARAMETER) {
type = annotation.target().asMethodParameter().type();
} else {
throw new IllegalStateException("Unsupported target:" + annotation.target());
}
if (type.kind() != Type.Kind.CLASS) {
throw new IllegalStateException("Invalid type: " + type);
}
ClassInfo injectedClazz = index.getClassByName(type.name());
if (injectedClazz == null) {
throw new IllegalStateException("Injected class not found in index: " + type.name());
}
if (!injectedClazz.isInterface()
&& !injectedClazz.hasNoArgsConstructor()) {
throw new IllegalStateException(
"@CachedResults class must be an interface or declare a no-args constructor: " + injectedClazz);
}
return new CachedResultsInjectConfig(cacheName, lockTimeout, keyGenerator, injectedClazz,
// consider all but @CachedResults and @Inject
annotation.target().declaredAnnotations().stream().filter(
a -> !a.name().equals(CACHED_RESULTS)
&& !a.name().equals(INJECT))
.toList(),
exclude);
}View on GitHub (pinned to e1c734241f)
Solutions
- Declare the injected field/parameter with a raw class or interface type (no generics, no arrays).
- If you need a parameterized type, introduce a dedicated non-generic interface/class and inject that.
- Check for compiler/Lombok/annotation-processor artifacts altering the declared type signature.
Example fix
// before @Inject @CachedResults List<CachedResult> results; // after @Inject @CachedResults CachedResultList results; // plain interface/class type
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the annotated injection point declares a raw class/interface type
Field f = MyClass.class.getDeclaredField("result");
if (f.getGenericType() instanceof ParameterizedType || f.getType().isArray()) {
throw new IllegalStateException("@CachedResults target must be a plain class/interface type");
} Type guard
static boolean isPlainClassType(java.lang.reflect.Field f) {
return !f.getGenericType().toString().contains("<") && !f.getType().isArray();
} Prevention
- Avoid generic or array types on @CachedResults injection points
- Create a dedicated non-generic interface for cached results
- Compile early — this fails at build time, before deployment
When it happens
Trigger: Annotating an injection point whose declared type is generic (e.g. `List<String>`), an array, a primitive wrapper resolved oddly, or a type variable rather than a plain class/interface type.
Common situations: Injecting `@CachedResults SomeGeneric<T>`, injecting an array type, or Kotlin/other-language generated signatures producing PARAMETERIZED_TYPE instead of CLASS.
Related errors
- Injected class not found in index:
- Unsupported wildcard type: ${wildcard}
- Unable to resolve input and output types for handler class <
- Unsupported target:
- @CachedResults class must be an interface or declare a no-ar
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/19248a0320fd81f5.
Report an issue: GitHub.