google/gson · critical · RuntimeException

Failed to invoke constructor '{constructor}' with no args

Error message

Failed to invoke constructor '{constructor}' with no args

What it means

newDefaultConstructor reflectively invokes the no-args constructor; InstantiationException indicates the JVM refused instantiation (class is abstract, array, primitive, or interface — though abstract is pre-filtered). It is wrapped as RuntimeException with the constructor signature.

Source

Thrown at gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java:268

    // Only try to make accessible if allowed; in all other cases checks above should
    // have verified that constructor is accessible
    if (filterResult == FilterResult.ALLOW) {
      String exceptionMessage = ReflectionHelper.tryMakeAccessible(constructor);
      if (exceptionMessage != null) {
        return new ThrowingObjectConstructor<>(exceptionMessage);
      }
    }

    return () -> {
      try {
        @SuppressWarnings("unchecked") // T is the same raw type as is requested
        T newInstance = (T) constructor.newInstance();
        return newInstance;
      }
      // Note: InstantiationException should be impossible because check at start of method made
      // sure that class is not abstract
      catch (InstantiationException e) {
        throw new RuntimeException(
            "Failed to invoke constructor '"
                + ReflectionHelper.constructorToString(constructor)
                + "' with no args",
            e);
      } catch (InvocationTargetException e) {
        // TODO: don't wrap if cause is unchecked?
        // TODO: JsonParseException ?
        throw new RuntimeException(
            "Failed to invoke constructor '"
                + ReflectionHelper.constructorToString(constructor)
                + "' with no args",
            e.getCause());
      } catch (IllegalAccessException e) {
        throw ReflectionHelper.createExceptionForUnexpectedIllegalAccess(e);
      }
    };
  }

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Register an InstanceCreator<T> supplying a concrete instance.
  2. Target a concrete subclass instead of an abstract/interface type.
  3. Register a TypeAdapter<T> that constructs the object manually.
  4. Ensure the type is a normal top-level or static nested class, not a local/anonymous one.

Example fix

// before
Gson gson = new Gson();
AbstractShape s = gson.fromJson(json, AbstractShape.class);

// after
Gson gson = new GsonBuilder()
    .registerTypeAdapter(AbstractShape.class, (InstanceCreator<AbstractShape>) t -> new Circle())
    .create();
Defensive patterns

Strategy: fallback

Validate before calling

if (Modifier.isAbstract(rawType.getModifiers()) || rawType.isInterface() || rawType.isArray()) {
  // cannot instantiate via reflection; register InstanceCreator
}

Type guard

boolean isReflectivelyInstantiable(Class<?> c) {
  return !c.isInterface() && !Modifier.isAbstract(c.getModifiers())
      && !c.isArray() && !c.isPrimitive();
}

Try / catch

try {
  return gson.fromJson(json, type);
} catch (RuntimeException ex) {
  if (ex.getMessage().contains("Failed to invoke constructor")) {
    // register InstanceCreator/TypeAdapter and retry with concrete subtype
  }
  throw ex;
}

Prevention

When it happens

Trigger: Deserializing into an abstract class that slipped past the abstract check via a synthetic bridge; an array or interface type reaching the reflective path; class loaded with a non-instantiable metadata shape.

Common situations: Rare; usually follows a custom InstanceCreator/TypeAdapter wiring bug; reflective binding to types Gson cannot allocate (local/anonymous classes, arrays as bean types).

Related errors


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/377dcbff995123b3.json. Report an issue: GitHub.