{"record":{"id":"3874de0672460d8d","repo":"google/gson","slug":"interfaces-can-t-be-instantiated-register-an-inst","errorCode":null,"errorMessage":"Interfaces can't be instantiated! Register an InstanceCreator or a TypeAdapter for this type. Interface name: ${c.getName()}","messagePattern":"Interfaces can't be instantiated! Register an InstanceCreator or a TypeAdapter for this type\\. Interface name: (.+?)","errorType":"exception","errorClass":"JsonIOException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java","lineNumber":424,"sourceCode":"   * ObjectConstructor}, which would then choose another way of creating the object. And it supports\n   * types which are only serialized but not deserialized (compared to directly throwing an\n   * exception when the {@code ObjectConstructor} is requested), e.g. when the runtime type of an\n   * object is inaccessible, but the compile-time type is accessible.\n   */\n  private static final class ThrowingObjectConstructor<T> implements ObjectConstructor<T> {\n    private final String exceptionMessage;\n\n    ThrowingObjectConstructor(String exceptionMessage) {\n      this.exceptionMessage = exceptionMessage;\n    }\n\n    @Override\n    public T construct() {\n      // New exception is created every time to avoid keeping a reference to an exception with\n      // potentially long stack trace, causing a memory leak\n      // (which would happen if the exception was already created when the\n      // `ThrowingObjectConstructor` is created)\n      throw new JsonIOException(exceptionMessage);\n    }\n  }\n\n  private static final class InstanceCreatorConstructor<T> implements ObjectConstructor<T> {\n    private final InstanceCreator<T> instanceCreator;\n    private final Type type;\n\n    InstanceCreatorConstructor(InstanceCreator<T> instanceCreator, Type type) {\n      this.instanceCreator = instanceCreator;\n      this.type = type;\n    }\n\n    @Override\n    public T construct() {\n      return instanceCreator.createInstance(type);\n    }\n  }\n}","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java#L406-L442","documentation":"Thrown when Gson attempts to deserialize into an interface type and no InstanceCreator or TypeAdapter is registered. Interfaces cannot be instantiated by any mechanism (reflection, Unsafe, special constructors), so Gson throws this via ThrowingObjectConstructor.construct(). The message names the interface.","triggerScenarios":"Calling gson.fromJson(json, SomeInterface.class) or having an interface-typed field that Gson must populate, where SomeInterface has no registered InstanceCreator or TypeAdapter.","commonSituations":"Deserializing into interface-typed fields (e.g. List vs ArrayList is fine, but custom interfaces are not); DI-managed types; missing adapter registration; polymorphic type handling without RuntimeTypeAdapterFactory.","solutions":["Register an InstanceCreator for the interface returning a concrete implementation","Register a TypeAdapter for the interface","Deserialize into a concrete implementation class instead of the interface","Use RuntimeTypeAdapterFactory (from gson-extras) for polymorphic deserialization"],"exampleFix":"// before\ngson.fromJson(json, Runnable.class);\n\n// after\ngsonBuilder.registerTypeAdapter(Runnable.class,\n  (InstanceCreator<Runnable>) type -> new MyRunnableImpl());","handlingStrategy":"validation","validationCode":"// Check if the target type is an interface before deserializing\nClass<?> c = (Class<?>) targetType;\nif (c.isInterface()) {\n  throw new IllegalArgumentException(\n    \"Cannot deserialize into interface \" + c.getName() + \"; register InstanceCreator\");\n}","typeGuard":"static boolean isDeserializableWithoutAdapter(Class<?> c) {\n  return !c.isInterface() && !Modifier.isAbstract(c.getModifiers());\n}","tryCatchPattern":"try {\n  return gson.fromJson(json, targetInterface);\n} catch (JsonIOException e) {\n  if (e.getMessage().startsWith(\"Interfaces can't be instantiated\")) {\n    // register an InstanceCreator for the interface and retry\n    throw new MyParseException(\"Need InstanceCreator for interface \" + targetInterface, e);\n  }\n  throw e;\n}","preventionTips":["Register an InstanceCreator for every interface type you deserialize into","Prefer deserializing into concrete implementation classes","Use RuntimeTypeAdapterFactory for polymorphic interface hierarchies","Audit interface-typed fields in your model classes"],"tags":["interface","instantiation","instance-creator","deserialization"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}