{"record":{"id":"56415afe23cd6c06","repo":"eclipse-vertx/vert.x","slug":"expecting-the-current-parser-token-to-be-the-start-56415a","errorCode":null,"errorMessage":"Expecting the current parser token to be the start of an object","messagePattern":"Expecting the current parser token to be the start of an object","errorType":"exception","errorClass":"DecodeException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/JacksonCodec.java","lineNumber":275,"sourceCode":"        return Boolean.TRUE;\n      case JsonTokenId.ID_FALSE:\n        return Boolean.FALSE;\n      case JsonTokenId.ID_NULL:\n        return null;\n      default:\n        throw new DecodeException(\"Unexpected token\"/*, parser.getCurrentLocation()*/);\n    }\n  }\n\n  /**\n   * Parse a JSON object given the {@code parser}, the parser current token must be {@link JsonTokenId#ID_START_OBJECT}\n   *\n   * @param parser the parser\n   * @return the parsed object\n   */\n  public static Map<String, Object> parseObject(JsonParser parser) throws IOException {\n    if (parser.currentTokenId() != JsonTokenId.ID_START_OBJECT) {\n      throw new DecodeException(\"Expecting the current parser token to be the start of an object\");\n    }\n    return internalParseObject(parser);\n  }\n\n  private static Map<String, Object> internalParseObject(JsonParser parser) throws IOException {\n    String key1 = parser.nextName();\n    if (key1 == null) {\n      return new LinkedHashMap<>(2);\n    }\n    parser.nextToken();\n    Object value1 = parseValue(parser);\n    String key2 = parser.nextName();\n    if (key2 == null) {\n      LinkedHashMap<String, Object> obj = new LinkedHashMap<>(2);\n      obj.put(key1, value1);\n      return obj;\n    }\n    parser.nextToken();","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/JacksonCodec.java#L257-L293","documentation":"JacksonCodec.parseObject requires the JsonParser's current token to be START_OBJECT before it begins parsing; otherwise it throws DecodeException. This API is meant to be called when the caller has already positioned/peeked the parser at an object start. Passing a parser positioned at a scalar, array, or a not-yet-started token is a programming/usage error.","triggerScenarios":"Calling JacksonCodec.parseObject(parser) when the current token is ID_START_ARRAY (the input is an array), a scalar value, or before advancing the parser to the first token of a fresh document (e.g. parser created but nextToken/currentToken not yet pointing at the object).","commonSituations":"Decoding a JSON array with an API that only accepts objects; manually managing a JsonParser and forgetting to advance to the first token; a producer that changed the payload from an object to an array.","solutions":["Advance/position the parser to the object start token before calling parseObject (call parser.nextToken() so currentTokenId() == ID_START_OBJECT)","Check the input shape first: if it starts with '[', call parseArray instead of parseObject","Validate the payload is a JSON object before decoding (e.g. trimmed input starts with '{')"],"exampleFix":"// before\nJsonParser p = mapper.createParser(\"[1,2]\");\nMap<String,Object> m = JacksonCodec.parseObject(p); // DecodeException\n// after\nJsonParser p = mapper.createParser(\"[1,2]\");\nif (p.nextToken() == JsonToken.START_ARRAY) {\n  List<Object> l = JacksonCodec.parseArray(p);\n} else {\n  Map<String,Object> m = JacksonCodec.parseObject(p);\n}","handlingStrategy":"type-guard","validationCode":"String t = input.trim();\nif (!t.startsWith(\"{\")) throw new IllegalArgumentException(\"expected a JSON object\");","typeGuard":"static boolean isJsonObjectToken(JsonParser p) {\n  return p.currentTokenId() == JsonTokenId.ID_START_OBJECT;\n}","tryCatchPattern":"try {\n  Map<String,Object> m = JacksonCodec.parseObject(parser);\n} catch (DecodeException e) {\n  // parser not positioned on START_OBJECT — inspect token and dispatch\n}","preventionTips":["Always call parser.nextToken() so the current token is the first token before parseObject","Dispatch on the leading character '{' vs '[' before choosing parseObject/parseArray","Verify producer contract: object-typed endpoints should reject array payloads upstream"],"tags":["java","json","decoding","parser-state"],"backgroundTag":"json-parse-error","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}