google/gson · error · IllegalArgumentException
Raw type {} is not supported because it requires specifying
Error message
Raw type {} is not supported because it requires specifying an owner type What it means
Thrown by TypeToken.getParameterized when GsonTypes.requiresOwnerType(rawType) returns true (TypeToken.java:414-420). Some generic classes are inner (non-static nested) classes whose generic signature requires an enclosing instance type, and getParameterized cannot supply an owner type, so creating such a ParameterizedType would be ambiguous. The check runs before delegating to ParameterizedTypeImpl to surface a clear error instead of a misleading internal failure.
Source
Thrown at gson/src/main/java/com/google/gson/reflect/TypeToken.java:416
int expectedArgsCount = typeVariables.length;
int actualArgsCount = typeArguments.length;
if (actualArgsCount != expectedArgsCount) {
throw new IllegalArgumentException(
rawClass.getName()
+ " requires "
+ expectedArgsCount
+ " type arguments, but got "
+ actualArgsCount);
}
// For legacy reasons create a TypeToken(Class) if the type is not generic
if (typeArguments.length == 0) {
return get(rawClass);
}
// Check for this here to avoid misleading exception thrown by ParameterizedTypeImpl
if (GsonTypes.requiresOwnerType(rawType)) {
throw new IllegalArgumentException(
"Raw type "
+ rawClass.getName()
+ " is not supported because it requires specifying an owner type");
}
for (int i = 0; i < expectedArgsCount; i++) {
Type typeArgument =
Objects.requireNonNull(typeArguments[i], "Type argument must not be null");
Class<?> rawTypeArgument = GsonTypes.getRawType(typeArgument);
TypeVariable<?> typeVariable = typeVariables[i];
for (Type bound : typeVariable.getBounds()) {
Class<?> rawBound = GsonTypes.getRawType(bound);
if (!rawBound.isAssignableFrom(rawTypeArgument)) {
throw new IllegalArgumentException(
"Type argument "
+ typeArgumentView on GitHub (pinned to 310ac341f2)
Solutions
- Make the nested class static (preferred) so it no longer requires an owner type.
- If you cannot change the class, construct the ParameterizedType manually via java.lang.reflect.ParameterizedType or GsonTypes.newParameterizedTypeWithOwner(owner, raw, args) supplying the owner type.
- Use an anonymous TypeToken subclass new TypeToken<Outer.Inner<X>>(){} when the type is known at compile time.
- Prefer a top-level class or interface for the generic contract.
Example fix
// before
class Builder<T> { ... } // non-static inner of Outer
TypeToken<?> t = TypeToken.getParameterized(Outer.Builder.class, String.class);
// after
static class Builder<T> { ... } // static nested, no owner needed
TypeToken<?> t = TypeToken.getParameterized(Outer.Builder.class, String.class); Defensive patterns
Strategy: validation
Validate before calling
Class<?> raw = SomeInner.class;
if (Modifier.isStatic(raw.getModifiers()) == false && raw.getEnclosingClass() != null
&& raw.getTypeParameters().length > 0) {
// likely requires owner; avoid getParameterized, build manually with owner
}
TypeToken<?> t = TypeToken.getParameterized(raw, args); Type guard
static boolean likelyNeedsOwnerType(Class<?> raw) {
return !Modifier.isStatic(raw.getModifiers())
&& raw.getEnclosingClass() != null;
} Try / catch
try {
return TypeToken.getParameterized(raw, args);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("owner type")) {
return TypeToken.get(GsonTypes.newParameterizedTypeWithOwner(owner, raw, args));
}
throw e;
} Prevention
- Prefer static nested classes for generic types used with reflection.
- If you must use a non-static inner class, supply an explicit owner type.
- Cache resolved TypeTokens rather than reconstructing on every call.
When it happens
Trigger: Calling TypeToken.getParameterized(SomeOuter.SomeInner.class, ...) where SomeInner is a non-static inner (member) class declaring its own type parameters. Also triggered by generic inner classes of classes like java.util.Map.Entry used as a raw type with type arguments when the reflection API demands an owner.
Common situations: Reflecting over framework-defined nested generic types (e.g. entry subclasses, builders defined as inner classes); using a library whose public API exposes a parameterized non-static nested class; converting code that worked with TypeToken<Map<K,V>> to a custom nested builder type.
Related errors
- {} requires {} type arguments, but got {}
- Type argument {} does not satisfy bounds for type variable {
- Must specify owner type for ${rawType}
- Primitive type is not allowed
- At most one lower bound is supported
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/e10ab86026a65c18.
Report an issue: GitHub.