eclipse-vertx/vert.x · error · DecodeException
Expecting the current parser token to be the start of an obj
Error message
Expecting the current parser token to be the start of an object
What it means
JacksonCodec.parseObject(JsonParser) requires the parser's current token to be START_OBJECT. When it is not, it throws DecodeException("Expecting the current parser token to be the start of an object"). This guards callers who explicitly ask to parse an object but position the parser at a different token (e.g. the start of an array or a scalar).
Source
Thrown at vertx-core/src/main/java/io/vertx/core/json/jackson/JacksonCodec.java:322
return Boolean.TRUE;
case JsonTokenId.ID_FALSE:
return Boolean.FALSE;
case JsonTokenId.ID_NULL:
return null;
default:
throw new DecodeException("Unexpected token"/*, parser.getCurrentLocation()*/);
}
}
/**
* Parse a JSON object given the {@code parser}, the parser current token must be {@link JsonTokenId#ID_START_OBJECT}
*
* @param parser the parser
* @return the parsed object
*/
public static Map<String, Object> parseObject(JsonParser parser) throws IOException {
if (parser.currentTokenId() != JsonTokenId.ID_START_OBJECT) {
throw new DecodeException("Expecting the current parser token to be the start of an object");
}
return internalParseObject(parser);
}
private static Map<String, Object> internalParseObject(JsonParser parser) throws IOException {
String key1 = parser.nextFieldName();
if (key1 == null) {
return new LinkedHashMap<>(2);
}
parser.nextToken();
Object value1 = parseValue(parser);
String key2 = parser.nextFieldName();
if (key2 == null) {
LinkedHashMap<String, Object> obj = new LinkedHashMap<>(2);
obj.put(key1, value1);
return obj;
}
parser.nextToken();View on GitHub (pinned to fb308bd8c3)
Solutions
- Check the payload's first non-whitespace character: use parseArray (or JsonDecoder for arrays) if it starts with '['
- Inspect the actual response shape (curl/log it) and decode into the matching type (JsonObject vs JsonArray)
- If the shape can vary, peek at the first token and branch on ID_START_OBJECT vs ID_START_ARRAY
- Fix or wrap the upstream to return a top-level object if a map is required
Example fix
// before
JsonObject obj = (JsonObject) Json.decodeValue(body); // body is '[...]'
// after
Object parsed = Json.decodeValue(body);
if (parsed instanceof JsonArray arr) {
processList(arr);
} else if (parsed instanceof JsonObject obj) {
processObject(obj);
} else {
throw new IllegalStateException("Unexpected JSON shape");
} Defensive patterns
Strategy: type-guard
Validate before calling
// Java
public static boolean isJsonObjectPayload(String s) {
return s != null && s.stripLeading().startsWith("{");
} Type guard
public static Object decodeFlexible(String s) {
String t = s == null ? "" : s.stripLeading();
if (t.startsWith("{")) return new io.vertx.core.json.JsonObject(s);
if (t.startsWith("{".substring(0,0) + "[")) return new io.vertx.core.json.JsonArray(s);
return null; // scalar or invalid
} Try / catch
try {
return JacksonCodec.parseObject(parser);
} catch (DecodeException e) {
if (e.getMessage().contains("start of an object")) {
// parser sits on an array/scalar — handle alternative shape
if (parser.currentTokenId() == com.fasterxml.jackson.core.JsonTokenId.ID_START_ARRAY) {
return JacksonCodec.parseArray(parser);
}
}
throw e;
} Prevention
- Inspect the first non-whitespace character to choose object vs array decoding
- Pin API contracts: expect a top-level object and validate upstream changes
- Decode with Json.decodeValue into Object and instanceof-check the result
- Add contract tests against real response shapes
When it happens
Trigger: Calling JacksonCodec.parseObject(parser) (or fromParser targeting a Map type) when the parser's current token is ID_START_ARRAY, a scalar value, or null/no token — i.e. the input is a JSON array, string, number, boolean, null, or empty.
Common situations: Decoding an API response that is a top-level JSON array (e.g. a list of items) into a Map/JsonObject; decoding an empty body; a producer changed its response shape from object to array; cursor mispositioning after manual parser use.
Related errors
- Expecting the current parser token to be the start of an arr
- Failed to decode:${e.getMessage()}
- Failed to decode:
- Failed to decode:
- Failed to decode
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/0422d93bbc03f45d.
Report an issue: GitHub.