dotnet/aspnetcore · error · RuntimeException
TypeReference must be instantiated with a type parameter…
Error message
TypeReference must be instantiated with a type parameter such as (new TypeReference<Foo<Bar>>() {}). What it means
TypeReference<T> uses the super-type-token pattern: it captures T by reflecting the generic superclass of an anonymous subclass. If the subclass is not parameterized (e.g. 'new TypeReference()' with no <...>), getGenericSuperclass() is a Class, not a ParameterizedType, so the cast throws ClassCastException which is caught and rethrown as a RuntimeException with this message.
Solutions
- Always create TypeReference as an anonymous inner class WITH the type argument: new TypeReference<List<Integer>>() {}.
- Store the instance in a field typed with the parameter so the compiler keeps it: TypeReference<List<Integer>> listType = new TypeReference<List<Integer>>() {};.
- If you need a non-generic type, pass the Class directly (e.g. invoke(String.class, ...)) instead of TypeReference.
Example fix
// before
TypeReference ref = new TypeReference(); // raw -> throws
// after
TypeReference<List<Integer>> ref = new TypeReference<List<Integer>>() {}; Defensive patterns
Strategy: type-guard
Type guard
// Validate at construction that the subclass is parameterized.
public static <T> TypeReference<T> checked(TypeReference<T> ref) {
if (ref.getType() == null) {
throw new IllegalArgumentException("TypeReference missing type parameter");
}
return ref;
} Try / catch
try {
TypeReference<?> ref = new TypeReference() {}; // raw
} catch (RuntimeException e) {
if (e.getMessage().contains("TypeReference must be instantiated")) {
// guide developer to add the type parameter
} else throw e;
} Prevention
- Always write 'new TypeReference<X>() {}' with the angle brackets.
- Assign to a parameterized field so the IDE keeps the generic.
- Prefer Class-based overloads when the type is non-generic.
When it happens
Trigger: Instantiating 'new TypeReference()' (raw) instead of 'new TypeReference<Map<String,Integer>>() {}'. Also reached if someone subclasses TypeReference without specifying the type parameter.
Common situations: Copy-paste error omitting the generic; using TypeReference as a field of a non-parameterized class; refactor that lost the angle brackets; tooling/codegen that strips generics.
Related errors
- Cannot handle type class:
- A valid url is required.
- A valid url is required.
- Cannot handle type class
- Connection is not active.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/06c30b65af07f1fe.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/TypeReference.java:40
* spite of type erasure since, sadly, {@code Foo<Bar>.class} is not valid Java.
*
* To get the Type of Class {@code Foo<Bar>}, use the following syntax:
* <pre>{@code
* Type fooBarType = (new TypeReference<Foo<Bar>>() { }).getType();
* }</pre>
*
* To get the Type of class Foo, use a regular Type Token:
* <pre>{@code
* Type fooType = Foo.class;
* }</pre>
*
* @see <a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html">Super Type Tokens</a>
*/
public TypeReference() {
try {
this.type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
} catch (ClassCastException ex) {
throw new RuntimeException("TypeReference must be instantiated with a type parameter such as (new TypeReference<Foo<Bar>>() {}).");
}
}
/**
* Gets the referenced type.
* @return The Type encapsulated by this TypeReference
*/
public Type getType() {
return this.type;
}
}
View on GitHub (pinned to 3600ca084e)