{"record":{"id":"3aec2295853ab9ef","repo":"google/gson","slug":"failed-to-invoke-constructor-reflectionhelper-c","errorCode":null,"errorMessage":"Failed to invoke constructor '${ReflectionHelper.constructorToString(constructor)}' with no args","messagePattern":"Failed to invoke constructor '(.+?)' with no args","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java","lineNumber":268,"sourceCode":"    // Only try to make accessible if allowed; in all other cases checks above should\n    // have verified that constructor is accessible\n    if (filterResult == FilterResult.ALLOW) {\n      String exceptionMessage = ReflectionHelper.tryMakeAccessible(constructor);\n      if (exceptionMessage != null) {\n        return new ThrowingObjectConstructor<>(exceptionMessage);\n      }\n    }\n\n    return () -> {\n      try {\n        @SuppressWarnings(\"unchecked\") // T is the same raw type as is requested\n        T newInstance = (T) constructor.newInstance();\n        return newInstance;\n      }\n      // Note: InstantiationException should be impossible because check at start of method made\n      // sure that class is not abstract\n      catch (InstantiationException e) {\n        throw new RuntimeException(\n            \"Failed to invoke constructor '\"\n                + ReflectionHelper.constructorToString(constructor)\n                + \"' with no args\",\n            e);\n      } catch (InvocationTargetException e) {\n        // TODO: don't wrap if cause is unchecked?\n        // TODO: JsonParseException ?\n        throw new RuntimeException(\n            \"Failed to invoke constructor '\"\n                + ReflectionHelper.constructorToString(constructor)\n                + \"' with no args\",\n            e.getCause());\n      } catch (IllegalAccessException e) {\n        throw ReflectionHelper.createExceptionForUnexpectedIllegalAccess(e);\n      }\n    };\n  }\n","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java#L250-L286","documentation":"Thrown when Constructor.newInstance() raises InstantiationException while invoking a located no-args constructor. The source comment states this should be impossible because abstract classes are filtered earlier, so it indicates a runtime inconsistency — typically R8/proguard altering the class after Gson's static checks, or exotic classloader/JVM behavior.","triggerScenarios":"A no-args constructor is found and the class passed the non-abstract check, but newInstance() still throws InstantiationException — e.g. the class became abstract at runtime after shrinking, or the constructor was removed between discovery and invocation.","commonSituations":"Android R8/proguard stripping or modifying classes; hot-swapped or dynamically-generated classes changing between discovery and use; unusual JVM/classloader behavior.","solutions":["Register an InstanceCreator or TypeAdapter for the type to bypass reflective construction","Ensure R8/ProGuard keep rules preserve the no-args constructor: -keep class com.example.MyClass { <init>(); }","Verify the class is concrete and retains its no-args constructor in the shipped artifact"],"exampleFix":"// before - R8 strips no-args ctor, class becomes abstract at runtime\n// (no explicit keep rule)\n\n// after - proguard-rules.pro\n-keep class com.example.MyModel { <init>(); }","handlingStrategy":"try-catch","validationCode":"// Verify the class is concrete and has a no-args constructor at setup time\nClass<?> c = MyType.class;\nif (Modifier.isAbstract(c.getModifiers())) throw new IllegalStateException(c + \" is abstract\");\ntry {\n  c.getDeclaredConstructor();\n} catch (NoSuchMethodException e) {\n  throw new IllegalStateException(c + \" needs a no-args constructor\", e);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return gson.fromJson(json, MyType.class);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Failed to invoke constructor\")) {\n    // class state changed at runtime; register InstanceCreator or fix keep rules\n    throw new MyParseException(\"Constructor invocation failed (R8/JVM issue?)\", e);\n  }\n  throw e;\n}","preventionTips":["Add R8/ProGuard keep rules preserving no-args constructors: -keep class com.example.MyClass { <init>(); }","Register an InstanceCreator for classes at risk of runtime modification","Verify classes are concrete and retain no-args constructors in the shipped artifact"],"tags":["constructor","reflection","instantiation","r8","proguard"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}