{"id":"afad088cc3c1ceba","repo":"google/gson","slug":"raw-type-rawclass-getname-is-not-support","errorCode":null,"errorMessage":"Raw type \" + rawClass.getName() + \" is not supported because it requires specifying an owner type","messagePattern":"Raw type \" \\+ rawClass\\.getName\\(\\) \\+ \" is not supported because it requires specifying an owner type","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/reflect/TypeToken.java","lineNumber":416,"sourceCode":"    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);\n    }\n\n    // Check for this here to avoid misleading exception thrown by ParameterizedTypeImpl\n    if (GsonTypes.requiresOwnerType(rawType)) {\n      throw new IllegalArgumentException(\n          \"Raw type \"\n              + rawClass.getName()\n              + \" is not supported because it requires specifying an owner type\");\n    }\n\n    for (int i = 0; i < expectedArgsCount; i++) {\n      Type typeArgument =\n          Objects.requireNonNull(typeArguments[i], \"Type argument must not be null\");\n      Class<?> rawTypeArgument = GsonTypes.getRawType(typeArgument);\n      TypeVariable<?> typeVariable = typeVariables[i];\n\n      for (Type bound : typeVariable.getBounds()) {\n        Class<?> rawBound = GsonTypes.getRawType(bound);\n\n        if (!rawBound.isAssignableFrom(rawTypeArgument)) {\n          throw new IllegalArgumentException(\n              \"Type argument \"\n                  + typeArgument","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/reflect/TypeToken.java#L398-L434","documentation":"Thrown by TypeToken.getParameterized when the raw class requires an owner type (GsonTypes.requiresOwnerType returns true). Inner non-static member classes and certain nested types carry an implicit owner instance, and Gson cannot construct a correct parameterized type without that owner being specified. Rather than emit a malformed type, getParameterized rejects it up front.","triggerScenarios":"Passing a non-static inner class (e.g. an inner class Outer.Inner) as rawType to getParameterized. Because the class is declared as a member of Outer, its ParameterizedTypeImpl would need an owner type, which getParameterized always sets to null (TypeToken.java:443).","commonSituations":"Deserializing into a non-static inner class whose enclosing instance cannot be supplied by Gson; using model classes that were accidentally declared non-static (common in DTO/VO code reviews); working with nested builder classes.","solutions":["Make the inner class static so it no longer requires an owner type.","Use a top-level class or a static nested class for the target type.","If you cannot change the class, construct the parameterized type with an explicit owner using GsonTypes.newParameterizedTypeWithOwner(ownerType, rawClass, typeArgs).","Deserialize into the raw class via TypeToken.get(rawClass) if generics are not needed."],"exampleFix":"// before\nclass Outer {\n  class Inner<T> { T value; } // non-static, needs owner\n}\nTypeToken.getParameterized(Outer.Inner.class, String.class); // throws\n\n// after\nclass Outer {\n  static class Inner<T> { T value; } // static, no owner needed\n}\nTypeToken.getParameterized(Outer.Inner.class, String.class);","handlingStrategy":"validation","validationCode":"import java.lang.reflect.Modifier;\n\nboolean isStaticOrTopLevel(Class<?> c) {\n  return c.getEnclosingClass() == null || Modifier.isStatic(c.getModifiers());\n}\n\n// before calling getParameterized:\nif (!isStaticOrTopLevel(rawClass)) {\n  throw new IllegalArgumentException(rawClass + \" requires an owner; make it static or use newParameterizedTypeWithOwner\");\n}","typeGuard":"static boolean isOwnerFree(Class<?> c) {\n  return c.getEnclosingClass() == null || Modifier.isStatic(c.getModifiers());\n}","tryCatchPattern":null,"preventionTips":["Prefer static nested classes or top-level classes for Gson target types.","Audit inner classes used as deserialization targets and add the 'static' modifier where possible.","Use GsonTypes.newParameterizedTypeWithOwner when an owner type is genuinely required.","Add a test that fails if a target class fails the owner-free check."],"tags":["gson","typetoken","inner-class","reflection"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}