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

  1. Always subclass with an explicit type parameter: new TypeRef<Map<String,Object>>() {}.
  2. Declare the subclass as class X extends TypeRef<Foo>, not TypeRef.
  3. 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

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&lt;Integer></code>: <pre>
 *   var TypeRef = new TypeRef&lt;List&lt;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)