google/gson · error · IllegalArgumentException

${contextRawType} is not the same as or a subtype of ${super

Error message

${contextRawType} is not the same as or a subtype of ${supertype}

What it means

Thrown by GsonTypes.getSupertype() as an internal invariant check: the requested supertype must be assignable from the contextRawType. If supertype.isAssignableFrom(contextRawType) is false, the call is logically invalid. This indicates a bug in type resolution or a custom TypeAdapterFactory passing an incorrect supertype.

Source

Thrown at gson/src/main/java/com/google/gson/internal/GsonTypes.java:288

  /**
   * Returns the generic form of {@code supertype}. For example, if this is {@code
   * ArrayList<String>}, this returns {@code Iterable<String>} given the input {@code
   * Iterable.class}.
   *
   * @param supertype a superclass of, or interface implemented by, this.
   */
  private static Type getSupertype(Type context, Class<?> contextRawType, Class<?> supertype) {
    if (context instanceof WildcardType) {
      // Wildcards are useless for resolving supertypes. As the upper bound has the same raw type,
      // use it instead
      Type[] bounds = ((WildcardType) context).getUpperBounds();
      // Currently the JLS only permits one bound for wildcards so using first bound is safe
      assert bounds.length == 1;
      context = bounds[0];
    }
    if (!supertype.isAssignableFrom(contextRawType)) {
      throw new IllegalArgumentException(
          contextRawType + " is not the same as or a subtype of " + supertype);
    }
    return resolve(
        context, contextRawType, GsonTypes.getGenericSupertype(context, contextRawType, supertype));
  }

  /**
   * Returns the component type of this array type.
   *
   * @throws ClassCastException if this type is not an array.
   */
  public static Type getArrayComponentType(Type array) {
    return array instanceof GenericArrayType
        ? ((GenericArrayType) array).getGenericComponentType()
        : ((Class<?>) array).getComponentType();
  }

  /**

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Verify the type hierarchy is correct: the supertype argument must be assignable from the raw type
  2. Fix custom TypeAdapterFactory logic to compute the correct supertype
  3. Ensure TypeTokens reflect real class/interface inheritance relationships

Example fix

// before - String is not a Number
GsonTypes.getSupertype(type, String.class, Number.class);

// after - Integer IS a Number
GsonTypes.getSupertype(type, Integer.class, Number.class);
Defensive patterns

Strategy: validation

Validate before calling

// Before computing a supertype relationship, verify assignability
Class<?> contextRawType = MyImpl.class;
Class<?> supertype = SomeInterface.class;
if (!supertype.isAssignableFrom(contextRawType)) {
  throw new IllegalArgumentException(
    contextRawType + " is not assignable from " + supertype);
}
// safe to resolve supertype

Type guard

static boolean isValidSupertype(Class<?> rawType, Class<?> supertype) {
  return supertype.isAssignableFrom(rawType);
}

Prevention

When it happens

Trigger: An internal or custom call to getSupertype(context, contextRawType, supertype) where the supertype is not actually a supertype of contextRawType — e.g. asking for Number.class as a supertype of String.class.

Common situations: Bugs in custom TypeAdapterFactory implementations; incorrect TypeToken hierarchies that don't reflect real inheritance; internal Gson edge cases with unusual generic bounds.

Related errors


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