{"id":"448868e961ce3558","repo":"google/gson","slug":"rawtype-must-be-of-type-class-but-was-rawtype","errorCode":null,"errorMessage":"rawType must be of type Class, but was \" + rawType","messagePattern":"rawType must be of type Class, but was \" \\+ rawType","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/reflect/TypeToken.java","lineNumber":393,"sourceCode":"   *\n   * As seen here the result is a {@code TypeToken<?>}; this method cannot provide any type-safety,\n   * and care must be taken to pass in the correct number of type arguments.\n   *\n   * <p>If {@code rawType} is a non-generic class and no type arguments are provided, this method\n   * simply delegates to {@link #get(Class)} and creates a {@code TypeToken(Class)}.\n   *\n   * @throws IllegalArgumentException If {@code rawType} is not of type {@code Class}, or if the\n   *     type arguments are invalid for the raw type\n   */\n  public static TypeToken<?> getParameterized(Type rawType, Type... typeArguments) {\n    Objects.requireNonNull(rawType);\n    Objects.requireNonNull(typeArguments);\n\n    // Perform basic validation here because this is the only public API where users\n    // can create malformed parameterized types\n    if (!(rawType instanceof Class)) {\n      // See also https://bugs.openjdk.org/browse/JDK-8250659\n      throw new IllegalArgumentException(\"rawType must be of type Class, but was \" + rawType);\n    }\n    Class<?> rawClass = (Class<?>) rawType;\n    TypeVariable<?>[] typeVariables = rawClass.getTypeParameters();\n\n    int expectedArgsCount = typeVariables.length;\n    int actualArgsCount = typeArguments.length;\n    if (actualArgsCount != expectedArgsCount) {\n      throw new IllegalArgumentException(\n          rawClass.getName()\n              + \" requires \"\n              + expectedArgsCount\n              + \" type arguments, but got \"\n              + actualArgsCount);\n    }\n\n    // For legacy reasons create a TypeToken(Class) if the type is not generic\n    if (typeArguments.length == 0) {\n      return get(rawClass);","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/reflect/TypeToken.java#L375-L411","documentation":"Thrown by TypeToken.getParameterized when the first argument (rawType) is not an instance of java.lang.Class. The API contract requires a Class so it can read its type parameters; passing any other Type (ParameterizedType, GenericArrayType, TypeVariable, WildcardType) is rejected. This mirrors OpenJDK bug JDK-8250659 referenced in the source.","triggerScenarios":"Calling TypeToken.getParameterized(someParameterizedType, ...) where someParameterizedType is itself a ParameterizedType or a Type obtained reflectively rather than a raw Class. The instanceof Class check at TypeToken.java:391 fails.","commonSituations":"Programmatically building nested generic types from reflectively-obtained Type objects; passing List.class vs a TypeToken's full getType() by mistake; copy-pasting from code that used GsonTypes.newParameterizedTypeWithOwner (which accepts Type) into getParameterized.","solutions":["Pass the raw Class as the first argument, e.g. TypeToken.getParameterized(Map.class, keyType, valueType).","If you already have a full Type (including type arguments), use TypeToken.get(type) instead of getParameterized.","Extract the raw class with GsonTypes.getRawType(type) and pass that to getParameterized.","For owner-type-bearing nested generics, use GsonTypes.newParameterizedTypeWithOwner directly."],"exampleFix":"// before\nType mapType = ...; // a ParameterizedType\nTypeToken.getParameterized(mapType, String.class); // throws\n\n// after\nTypeToken.getParameterized(Map.class, String.class, valueType);","handlingStrategy":"validation","validationCode":"import java.lang.reflect.Type;\n\nTypeToken<?> safeGetParameterized(Type rawType, Type... args) {\n  if (!(rawType instanceof Class)) {\n    // Either extract the raw class or use TypeToken.get for a fully-formed Type\n    Class<?> rawClass = com.google.gson.internal.GsonTypes.getRawType(rawType);\n    return TypeToken.getParameterized(rawClass, args);\n  }\n  return TypeToken.getParameterized(rawType, args);\n}","typeGuard":"static boolean isRawClassType(Type t) {\n  return t instanceof Class;\n}","tryCatchPattern":null,"preventionTips":["Always pass a Class as the first argument to TypeToken.getParameterized.","If you hold a full Type, use TypeToken.get(type) instead.","Use GsonTypes.getRawType(type) to coerce a Type to its raw Class when needed.","Document the rawType-is-Class contract on wrappers around getParameterized."],"tags":["gson","typetoken","reflection","api-misuse"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}