{"record":{"id":"6bd2dcb69af2142c","repo":"google/gson","slug":"typetoken-must-be-created-with-a-type-argument-ne","errorCode":null,"errorMessage":"TypeToken must be created with a type argument: new TypeToken<...>() {}; When using code shrinkers (ProGuard, R8, ...) make sure that generic signatures are preserved.\nSee {}","messagePattern":"TypeToken must be created with a type argument: new TypeToken<\\.\\.\\.>\\(\\) (.+?); When using code shrinkers \\(ProGuard, R8, \\.\\.\\.\\) make sure that generic signatures are preserved\\.\nSee (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/reflect/TypeToken.java","lineNumber":110,"sourceCode":"   * Verifies that {@code this} is an instance of a direct subclass of TypeToken and returns the\n   * type argument for {@code T} in {@link GsonTypes#canonicalize canonical form}.\n   */\n  private Type getTypeTokenTypeArgument() {\n    Type superclass = getClass().getGenericSuperclass();\n    if (superclass instanceof ParameterizedType) {\n      ParameterizedType parameterized = (ParameterizedType) superclass;\n      if (parameterized.getRawType() == TypeToken.class) {\n        Type typeArgument = GsonTypes.canonicalize(parameterized.getActualTypeArguments()[0]);\n\n        if (isCapturingTypeVariablesForbidden()) {\n          verifyNoTypeVariable(typeArgument);\n        }\n        return typeArgument;\n      }\n    }\n    // Check for raw TypeToken as superclass\n    else if (superclass == TypeToken.class) {\n      throw new IllegalStateException(\n          \"TypeToken must be created with a type argument: new TypeToken<...>() {}; When using code\"\n              + \" shrinkers (ProGuard, R8, ...) make sure that generic signatures are preserved.\"\n              + \"\\nSee \"\n              + TroubleshootingGuide.createUrl(\"type-token-raw\"));\n    }\n\n    // User created subclass of subclass of TypeToken\n    throw new IllegalStateException(\"Must only create direct subclasses of TypeToken\");\n  }\n\n  private static void verifyNoTypeVariable(Type type) {\n    if (type instanceof TypeVariable) {\n      TypeVariable<?> typeVariable = (TypeVariable<?>) type;\n      throw new IllegalArgumentException(\n          \"TypeToken type argument must not contain a type variable; captured type variable \"\n              + typeVariable.getName()\n              + \" declared by \"\n              + typeVariable.getGenericDeclaration()","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/reflect/TypeToken.java#L92-L128","documentation":"Thrown by TypeToken's protected constructor when the anonymous subclass's generic superclass is the RAW TypeToken class (no type argument supplied) rather than ParameterizedType<TypeToken<...>>. Gson cannot recover the missing type argument. The message explicitly calls out code shrinkers (ProGuard/R8) that strip generic signatures as a common cause.","triggerScenarios":"Writing `new TypeToken(){}` (no <...>), or a properly-written `new TypeToken<List<String>>(){}` whose generic signature was stripped at build time by ProGuard/R8 without -keepattributes Signature. Also possible when reflection over the class file does not return ParameterizedType due to compiler bugs.","commonSituations":"Android release builds with ProGuard/R8 missing Signature attribute retention; copying TypeToken usage without the empty anonymous-class body or without the type argument; obfuscation configs that strip Signature/InnerClasses; some older Android Gradle Plugin defaults.","solutions":["If using ProGuard/R8, add `-keepattributes Signature` (and typically `*Annotation*`, `InnerClasses`) to your rules; for R8 this is usually inherited from the default Android rules but verify.","Ensure TypeToken is instantiated as an anonymous subclass with an explicit type argument: `new TypeToken<List<String>>() {}` (note the empty `{}`).","If a type argument is only known at runtime, use TypeToken.getParameterized(...) instead of an anonymous subclass.","Update Gson and the Android Gradle Plugin; old AGP/Gson combinations occasionally drop signatures."],"exampleFix":"// before (broken)\nTypeToken<?> t = new TypeToken(){}; // raw, no type argument\n// or ProGuard stripped signature from:\nTypeToken<List<String>> t = new TypeToken<List<String>>(){};\n\n// after (code fix)\nTypeToken<List<String>> t = new TypeToken<List<String>>() {};\n\n// after (ProGuard fix in proguard-rules.pro):\n-keepattributes Signature, InnerClasses, EnclosingMethod\n-keep class com.google.gson.reflect.TypeToken\n-keep class * extends com.google.gson.reflect.TypeToken\n\n// after (runtime-known type):\nTypeToken<?> t = TypeToken.getParameterized(List.class, String.class);","handlingStrategy":"validation","validationCode":"// at app startup, verify generic signatures survive shrinking\nTypeToken<List<String>> t = new TypeToken<List<String>>() {};\nif (t.getType() instanceof Class) { // raw TypeToken, signature stripped\n  throw new IllegalStateException(\"Generic signatures stripped; add -keepattributes Signature\");\n}","typeGuard":"public static boolean typeTokenResolved(TypeToken<?> t) {\n  return !(t.getType() instanceof Class) || ((Class<?>) t.getType()).getTypeParameters().length == 0 && t.getType() != TypeToken.class;\n}","tryCatchPattern":"try {\n  TypeToken<List<String>> t = new TypeToken<List<String>>() {};\n  return gson.fromJson(json, t.getType());\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"TypeToken must be created with a type argument\")) {\n    throw new IllegalStateException(\"ProGuard/R8 stripped signatures; add -keepattributes Signature\", e);\n  }\n  throw e;\n}","preventionTips":["Add `-keepattributes Signature,InnerClasses,EnclosingMethod` to ProGuard/R8 rules.","Add a startup assertion that a known TypeToken resolves to a ParameterizedType.","Prefer TypeToken.getParameterized for runtime-known types.","Test release/obfuscated builds with a TypeToken round-trip, not just debug builds."],"tags":["gson","type-token","generics","proguard","r8","obfuscation","illegal-state"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}