eclipse-vertx/vert.x · error · DecodeException
Failed to decode:
Error message
Failed to decode:
What it means
DatabindCodec.adapt converts plain Jackson results (LinkedHashMap, ArrayList) into Vert.x JsonObject/JsonArray so decoded values match Vert.x JSON semantics. If any conversion throws (e.g. a map key that is not a String, or nested conversion failure), it is wrapped in DecodeException('Failed to decode: ' + cause message).
Source
Thrown at vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/DatabindCodec.java:208
.writeValue(writer, object);
} catch (Exception e) {
throw new EncodeException("Failed to encode as JSON: " + e.getMessage());
}
}
private static Object adapt(Object o) {
try {
if (o instanceof List) {
List list = (List) o;
return new JsonArray(list);
} else if (o instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) o;
return new JsonObject(map);
}
return o;
} catch (Exception e) {
throw new DecodeException("Failed to decode: " + e.getMessage());
}
}
}
View on GitHub (pinned to fb308bd8c3)
Solutions
- Check e.getMessage()/cause to find which value failed conversion.
- Ensure JSON object keys are strings — standard JSON guarantees this; fix producers emitting non-string keys via custom serializers.
- Decode into a concrete type (Class/TypeReference) instead of Object.class to bypass adapt().
- Construct JsonObject/JsonArray manually from the decoded Map/List if custom handling is needed.
Example fix
// before
Object o = Json.decodeValue(buf); // relies on adapt()
// after
Map<String,Object> m = Json.decodeValue(buf, new TypeReference<Map<String,Object>>(){}); Defensive patterns
Strategy: try-catch
Type guard
if (decoded instanceof Map<?,?> m && m.keySet().stream().allMatch(k -> k instanceof String)) {
JsonObject o = new JsonObject((Map<String,Object>) m);
} Try / catch
try {
Object o = Json.decodeValue(buf);
} catch (DecodeException e) {
log.error("adapt() failed: {}", e.getMessage());
} Prevention
- Prefer decoding into explicit types over Object.class.
- Guarantee producers emit string keys (standard JSON).
- Insert decoded objects into JsonObject only after confirming JsonObject/JsonArray types.
When it happens
Trigger: Decoding JSON into Object.class (Json.decodeValue(buf)) whose object keys are not Strings — e.g. '{"1":2}' is fine, but Jackson maps with non-String keys from custom deserializers; also nested structures failing the cast into JsonObject/JsonArray.
Common situations: Decoding to Object and inserting the result into another JsonObject; JSON with numeric-looking keys combined with custom key-type deserializers; programmatic Maps handed through the codec path with mixed key types.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to decode:
- Unexpected trailing token
- Failed to decode:${e.getMessage()}
- Mapping ${toValueType.getName()} is not available without J
- Failed to decode:
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/83213d22fa2410ea.
Report an issue: GitHub.