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
- Find the offending value type reported in the message (e.g. class java.time.Instant).
- Convert the value to a JSON-native type before putting it: instant.toString(), pojo.toJsonObject(), buffer.getBytes() for binary.
- Use JsonPojo/ValueConverter mappers (JsonMapper) so POJOs are encoded on put.
- 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
- Only put JSON-native values (String, Number, Boolean, null, Map, List, byte[]) into JsonObject.
- Convert Instant/Date to ISO strings and POJOs via their mappers on insert.
- Review any code that stores arbitrary Object in JsonObject before calling copy() or serializing.
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
- workerPoolSize must be > 0
- Invalid JSON array: ${json}
- Invalid JSON array: ${buf}
- Invalid JSON object: ${json}
- Invalid JSON object: ${buf}
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/c3769828dcd7bf7f.
Report an issue: GitHub.