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 "
                  + typeArgument

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Make the nested class static (preferred) so it no longer requires an owner type.
  2. 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.
  3. Use an anonymous TypeToken subclass new TypeToken<Outer.Inner<X>>(){} when the type is known at compile time.
  4. 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

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


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/e10ab86026a65c18. Report an issue: GitHub.