alibaba/spring-ai-alibaba · error · IllegalArgumentException
Internal error: TypeReference constructed without actual…
Error message
Internal error: TypeReference constructed without actual type information
What it means
TypeRef's protected constructor reads the generic superclass's type argument to capture the referenced type. If the subclass is constructed without type parameters (a raw or anonymous non-parameterized subclass), getGenericSuperclass() returns a plain Class and this IllegalArgumentException is thrown. It is a developer misuse error of the type-token pattern.
Solutions
- Always subclass with an explicit type parameter: new TypeRef<Map<String,Object>>() {}.
- Declare the subclass as class X extends TypeRef<Foo>, not TypeRef.
- Reuse a single constant TypeRef instance instead of creating raw ones inline.
Example fix
// before
TypeRef ref = new TypeRef() {};
// after
TypeRef<Map<String,Object>> ref = new TypeRef<Map<String,Object>>() {}; Defensive patterns
Strategy: validation
Validate before calling
// ensure the anonymous subclass carries a generic parameter
TypeRef<Map<String,Object>> ref = new TypeRef<Map<String,Object>>() {};
if (ref.getClass().getGenericSuperclass() instanceof Class) {
throw new IllegalArgumentException("TypeRef missing type parameter");
} Type guard
boolean isUsableTypeRef(TypeRef<?> ref) {
return !(ref.getClass().getGenericSuperclass() instanceof Class);
} Try / catch
try {
use(ref);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("TypeReference constructed without")) {
ref = new TypeRef<Map<String,Object>>() {}; // recreate with type argument
}
} Prevention
- Always write new TypeRef<T>() {} with an explicit type argument.
- Never instantiate raw TypeRef or TypeRef<?> without a body capturing T.
- Store shared TypeRef constants instead of ad-hoc raw instances.
When it happens
Trigger: new TypeRef() { } without a type argument, or instantiating a raw TypeRef subclass that does not encode a generic parameter, e.g. class MyRef extends TypeRef (no <T>).
Common situations: Copying a Jackson TypeReference-style snippet and forgetting the <T>; generating subclasses with erased generics; IDE quick-fix creating a non-generic subclass.
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/4c7496782adfebe5.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/utils/TypeRef.java:51
* implementation of <code>Comparable</code> (any such generic interface would do, as long
* as it forces a method with generic type to be implemented). to ensure that a Type
* argument is indeed given.
* <p>
* Usage is by sub-classing: here is one way to instantiate reference to generic type
* <code>List<Integer></code>: <pre>
* var TypeRef = new TypeRef<List<Integer>>() { };
* </pre> which can be passed to methods that accept TypeReference.
*
* @param <T>
*/
public abstract class TypeRef<T> implements Comparable<TypeRef<T>> {
protected final Type _type;
protected TypeRef() {
Type superClass = this.getClass().getGenericSuperclass();
if (superClass instanceof Class) {
throw new IllegalArgumentException(
"Internal error: TypeReference constructed without actual type information");
}
else {
this._type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}
}
public Type getType() {
return this._type;
}
@SuppressWarnings("unchecked")
public Optional<T> cast(Object obj) {
return erasureOf(this._type).filter(c -> c.isInstance(obj)).map(c -> (T) obj);
}
public static Optional<Class<?>> erasureOf(Type t) {
if (t instanceof Class<?> c) {View on GitHub (pinned to f82da0b50f)