{"id":"55692f9b127e11c4","repo":"google/gson","slug":"expected-a-class-parameterizedtype-or-genericarr","errorCode":null,"errorMessage":"Expected a Class, ParameterizedType, or GenericArrayType, but <{type}> is of type {className}","messagePattern":"Expected a Class, ParameterizedType, or GenericArrayType, but <(.+?)> is of type (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/GsonTypes.java","lineNumber":158,"sourceCode":"\n    } else if (type instanceof GenericArrayType) {\n      Type componentType = ((GenericArrayType) type).getGenericComponentType();\n      return Array.newInstance(getRawType(componentType), 0).getClass();\n\n    } else if (type instanceof TypeVariable) {\n      // we could use the variable's bounds, but that won't work if there are multiple.\n      // having a raw type that's more general than necessary is okay\n      return Object.class;\n\n    } else if (type instanceof WildcardType) {\n      Type[] bounds = ((WildcardType) type).getUpperBounds();\n      // Currently the JLS only permits one bound for wildcards so using first bound is safe\n      assert bounds.length == 1;\n      return getRawType(bounds[0]);\n\n    } else {\n      String className = type == null ? \"null\" : type.getClass().getName();\n      throw new IllegalArgumentException(\n          \"Expected a Class, ParameterizedType, or GenericArrayType, but <\"\n              + type\n              + \"> is of type \"\n              + className);\n    }\n  }\n\n  private static boolean equal(Object a, Object b) {\n    return Objects.equals(a, b);\n  }\n\n  /** Returns true if {@code a} and {@code b} are equal. */\n  public static boolean equals(Type a, Type b) {\n    @SuppressWarnings(\"ReferenceEquality\")\n    boolean areSame = a == b;\n    if (areSame) {\n      // also handles (a == null && b == null)\n      return true;","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/internal/GsonTypes.java#L140-L176","documentation":"GsonTypes.getRawType(Type) handles Class, ParameterizedType, GenericArrayType, TypeVariable, and WildcardType. Any other Type implementation (or null in legacy paths) is unexpected and throws IllegalArgumentException naming the actual class. It indicates a malformed/custom Type token was supplied to Gson's type resolution.","triggerScenarios":"Passing a custom java.lang.reflect.Type implementation, a null Type, or a Type produced by a buggy generic-resolution library; programmatic TypeToken construction with an unsupported Type variant.","commonSituations":"Hand-rolled TypeToken subclasses; integration with frameworks that synthesize Type objects; null returned by a broken TypeReference; JVM/bytecode-manipulation libraries emitting non-standard Types.","solutions":["Inspect the Type object passed to Gson/TypeToken and replace custom Types with standard Class, ParameterizedType, or GenericArrayType.","Ensure no null Type reaches Gson (defensive null-check at the API boundary).","Use TypeToken.of(class) or new TypeToken<MyType<T>>(){} to produce well-formed Types.","If a framework emits custom Types, write a TypeAdapter and bypass type resolution."],"exampleFix":"// before\nType weird = myFramework.makeType(...);\nTypeToken<?> token = TypeToken.get(weird); // throws\n\n// after\nTypeToken<List<String>> token = new TypeToken<List<String>>(){};","handlingStrategy":"validation","validationCode":"if (!(type instanceof Class || type instanceof ParameterizedType || type instanceof GenericArrayType)) {\n  throw new IllegalArgumentException(\"unsupported Type: \" + type);\n}\n","typeGuard":"boolean isSupportedType(Type t) {\n  return t instanceof Class\n      || t instanceof ParameterizedType\n      || t instanceof GenericArrayType\n      || t instanceof TypeVariable\n      || t instanceof WildcardType;\n}\n","tryCatchPattern":"try {\n  return gson.fromJson(json, type);\n} catch (IllegalArgumentException ex) {\n  if (ex.getMessage().startsWith(\"Expected a Class, ParameterizedType\")) {\n    // rebuild Type via TypeToken.of(MyClass.class)\n  }\n  throw ex;\n}\n","preventionTips":["Construct Types via TypeToken.of(class) or anonymous TypeToken subclasses.","Null-check Type values at API boundaries.","Avoid custom java.lang.reflect.Type implementations.","Validate Type objects from third-party frameworks before passing to Gson."],"tags":["type-resolution","generic-types","reflection","illegal-argument"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}