eclipse-vertx/vert.x · error · IllegalStateException

Illegal type in Json: ${o.getClass()}

Error message

Illegal type in Json: ${o.getClass()}

What it means

DEFAULT_CLONER is the fallback cloner used by JsonUtil.deepCopy when a value of an unsupported type is encountered during a deep copy of a JSON tree. Hitting it means the map/list being copied contains an object that is neither null, Map, List, String, Number, Boolean, nor byte[] (e.g. an Instant, POJO, or byte-buffer leaked into the JSON structure).

Source

Thrown at vertx-core/src/main/java/io/vertx/core/json/impl/JsonUtil.java:71

    if (val instanceof Map) {
      val = new JsonObject((Map) val);
    } else if (val instanceof List) {
      val = new JsonArray((List) val);
    } else if (val instanceof Instant) {
      val = ISO_INSTANT.format((Instant) val);
    } else if (val instanceof byte[]) {
      val = BASE64_ENCODER.encodeToString((byte[]) val);
    } else if (val instanceof Buffer) {
      val = BASE64_ENCODER.encodeToString(((Buffer) val).getBytes());
    } else if (val instanceof Enum) {
      val = ((Enum) val).name();
    }

    return val;
  }

  public static final Function<Object, ?> DEFAULT_CLONER = o -> {
    throw new IllegalStateException("Illegal type in Json: " + o.getClass());
  };

  @SuppressWarnings("unchecked")
  public static Object deepCopy(Object val, Function<Object, ?> copier) {
    if (val == null) {
      // OK
    } else if (val instanceof Number) {
      // OK
    } else if (val instanceof Boolean) {
      // OK
    } else if (val instanceof String) {
      // OK
    } else if (val instanceof Character) {
      // OK
    } else if (val instanceof CharSequence) {
      // CharSequences are not immutable, so we force toString() to become immutable
      val = val.toString();
    } else if (val instanceof Shareable) {

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Find the offending value type reported in the message (e.g. class java.time.Instant).
  2. Convert the value to a JSON-native type before putting it: instant.toString(), pojo.toJsonObject(), buffer.getBytes() for binary.
  3. Use JsonPojo/ValueConverter mappers (JsonMapper) so POJOs are encoded on put.
  4. If the type must be supported, register a custom cloner via JsonUtil options instead of relying on DEFAULT_CLONER.

Example fix

// before
jsonObject.put("createdAt", Instant.now());
jsonObject.copy(); // IllegalStateException: Illegal type in Json: class java.time.Instant
// after
jsonObject.put("createdAt", Instant.now().toString());
Defensive patterns

Strategy: type-guard

Validate before calling

for (Map.Entry<String, Object> e : map.entrySet()) {
  if (!isJsonNative(e.getValue())) throw new IllegalStateException("Non-JSON value at key: " + e.getKey());
}

Type guard

static boolean isJsonNative(Object v) {
  return v == null || v instanceof String || v instanceof Number || v instanceof Boolean
    || v instanceof Map || v instanceof List || v instanceof byte[];
}

Try / catch

try {
  JsonObject copy = jsonObject.copy();
} catch (IllegalStateException e) {
  // message names the offending class; convert it and retry
}

Prevention

When it happens

Trigger: Calling JsonObject.copy() / JsonUtil.deepCopy (or put of nested structures then copying) when the JsonObject was populated with non-JSON-native values such as java.time.Instant, java.math.BigDecimal is fine but a custom POJO, byte buffer wrapper, or Map with exotic value types is not.

Common situations: Developers put raw domain objects (POJOs, Instants, enums) into a JsonObject via mapValue converters that skipped wrapping; then a copy/serialization path walks the tree and cannot clone the foreign value. Often surfaces after upgrading Vert.x where cloner behavior changed.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/c3769828dcd7bf7f. Report an issue: GitHub.