{"record":{"id":"c85105748e1f1a06","repo":"eclipse-vertx/vert.x","slug":"invalid-type-obj-getclass-getname-to-put-i","errorCode":null,"errorMessage":"Invalid type: ${obj.getClass().getName()} to put in async map","messagePattern":"Invalid type: (.+?) to put in async map","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/shareddata/impl/SharedDataImpl.java","lineNumber":146,"sourceCode":"    LocalAsyncMapImpl<K, V> asyncMap = (LocalAsyncMapImpl<K, V>) localAsyncMaps.computeIfAbsent(name, n -> new LocalAsyncMapImpl<>(vertx));\n    ContextInternal context = vertx.getOrCreateContext();\n    return context.succeededFuture(new WrappedAsyncMap<>(asyncMap));\n  }\n\n  @Override\n  public Future<Counter> getLocalCounter(String name) {\n    Counter counter = localCounters.computeIfAbsent(name, n -> new AsynchronousCounter(vertx));\n    ContextInternal context = vertx.getOrCreateContext();\n    return context.succeededFuture(counter);\n  }\n\n  private static void checkType(Object obj) {\n    if (obj == null) {\n      throw new IllegalArgumentException(\"Cannot put null in key or value of async map\");\n    }\n    // All immutables and byte arrays are Serializable by the platform\n    if (!(obj instanceof Serializable || obj instanceof ClusterSerializable)) {\n      throw new IllegalArgumentException(\"Invalid type: \" + obj.getClass().getName() + \" to put in async map\");\n    }\n  }\n\n  public static final class WrappedAsyncMap<K, V> implements AsyncMap<K, V> {\n\n    private final AsyncMap<K, V> delegate;\n\n    WrappedAsyncMap(AsyncMap<K, V> other) {\n      this.delegate = other;\n    }\n\n    @Override\n    public Future<V> get(K k) {\n      checkType(k);\n      return delegate.get(k);\n    }\n\n    @Override","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/shareddata/impl/SharedDataImpl.java#L128-L164","documentation":"SharedDataImpl.checkType validates that keys/values put into an async map are either Serializable or ClusterSerializable so they can be marshalled across the cluster. Otherwise it throws IllegalArgumentException listing the offending class name.","triggerScenarios":"Calling put/putIfAbsent/replace on an AsyncMap (including getClusterWideMap / getAsyncMap results) with a non-null object whose class implements neither Serializable nor ClusterSerializable.","commonSituations":"Storing POJOs, third-party types (e.g. DateTime variants, streams, connections) into cluster maps; refactors dropped implements Serializable; type mismatch between dev (local map, lenient) and prod (cluster map, strict).","solutions":["Make the class implement Serializable (or ClusterSerializable for efficient binary encoding).","Convert to a supported type before storing: JsonObject, Buffer, String, byte[], boxed primitives.","Store a serializable DTO mapped from the domain object and convert back on read."],"exampleFix":"// before\nmap.put(\"user\", new User(\"a\")); // User not serializable -> IllegalArgumentException\n// after\nmap.put(\"user\", JsonObject.mapFrom(new User(\"a\")));","handlingStrategy":"type-guard","validationCode":"static boolean isMapCompatible(Object o) {\n  return o instanceof java.io.Serializable || o instanceof io.vertx.core.cluster.ClusterSerializable;\n}\nif (!isMapCompatible(key) || !isMapCompatible(value)) throw new IllegalArgumentException(\"type not storable in async map\");","typeGuard":"static boolean isMapCompatible(Object o) {\n  return o instanceof java.io.Serializable || o instanceof io.vertx.core.cluster.ClusterSerializable;\n}","tryCatchPattern":"try {\n  map.put(key, value);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Invalid type\")) {\n    map.put(key, JsonObject.mapFrom(value));\n  } else throw e;\n}","preventionTips":["Restrict async map contents to JsonObject, Buffer, String, byte[] and boxed primitives.","Add implements Serializable to DTO classes used across the cluster.","Test map writes in a clustered test to catch type issues early.","Document supported types where maps are exposed."],"tags":["shared-data","async-map","serialization","illegal-argument"],"backgroundTag":"incompatible-source-type","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}