{"record":{"id":"f91f99a85104ba85","repo":"eclipse-vertx/vert.x","slug":"expecting-the-current-parser-token-to-be-the-start-f91f99","errorCode":null,"errorMessage":"Expecting the current parser token to be the start of an array","messagePattern":"Expecting the current parser token to be the start of an array","errorType":"exception","errorClass":"DecodeException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/json/jackson/JacksonCodec.java","lineNumber":370,"sourceCode":"    obj.put(key2, value2);\n    do {\n      parser.nextToken();\n      Object value = parseValue(parser);\n      obj.put(key, value);\n      key = parser.nextFieldName();\n    } while (key != null);\n    return obj;\n  }\n\n  /**\n   * Parse a JSON array given the {@code parser}, the parser current token must be {@link JsonTokenId#ID_START_ARRAY}\n   *\n   * @param parser the parser\n   * @return the parsed array\n   */\n  public static List<Object> parseArray(JsonParser parser) throws IOException {\n    if (parser.currentTokenId() != JsonTokenId.ID_START_ARRAY) {\n      throw new DecodeException(\"Expecting the current parser token to be the start of an array\");\n    }\n    return internalParseArray(parser);\n  }\n\n  private static List<Object> internalParseArray(JsonParser parser) throws IOException {\n    List<Object> array = new ArrayList<>();\n    while (true) {\n      parser.nextToken();\n      int tokenId = parser.currentTokenId();\n      if (tokenId == JsonTokenId.ID_FIELD_NAME) {\n        throw new UnsupportedOperationException();\n      } else if (tokenId == JsonTokenId.ID_END_ARRAY) {\n        return array;\n      }\n      Object value = parseValue(parser);\n      array.add(value);\n    }\n  }","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/json/jackson/JacksonCodec.java#L352-L388","documentation":"JacksonCodec.parseArray(JsonParser) requires the parser's current token to be START_ARRAY. When it is not, it throws DecodeException(\"Expecting the current parser token to be the start of an array\"). This guards callers who explicitly ask to parse an array but position the parser at another token (e.g. an object or a scalar).","triggerScenarios":"Calling JacksonCodec.parseArray(parser) (or fromParser targeting a List type) when the parser's current token is ID_START_OBJECT, a scalar value, or null/no token — i.e. the input is a JSON object, string, number, boolean, null, or empty.","commonSituations":"Decoding a top-level JSON object into a List/JsonArray; decoding an empty response body; a producer changed its response shape from array to single object; wrapping a scalar endpoint result that used to be an array.","solutions":["Check the payload's first non-whitespace character: use parseObject (or decode to JsonObject) if it starts with '{'","Inspect the actual response shape and decode into the matching type (JsonArray vs JsonObject)","If the shape can vary, peek at the first token and branch on ID_START_ARRAY vs ID_START_OBJECT","Handle the single-object case by wrapping it in a list before/after decoding if a list is required"],"exampleFix":"// before\nJsonArray arr = (JsonArray) Json.decodeValue(body); // body is '{...}'\n// after\nObject parsed = Json.decodeValue(body);\nJsonArray arr = parsed instanceof JsonArray a ? a\n    : new JsonArray(java.util.List.of(parsed));\nprocessList(arr);","handlingStrategy":"type-guard","validationCode":"// Java\npublic static boolean isJsonArrayPayload(String s) {\n  return s != null && s.stripLeading().startsWith(\"[\");\n}","typeGuard":"public static Object decodeFlexible(String s) {\n  String t = s == null ? \"\" : s.stripLeading();\n  if (t.startsWith(\"[\")) return new io.vertx.core.json.JsonArray(s);\n  if (t.startsWith(\"{\")) return new io.vertx.core.json.JsonObject(s);\n  return null; // scalar or invalid\n}","tryCatchPattern":"try {\n  return JacksonCodec.parseArray(parser);\n} catch (DecodeException e) {\n  if (e.getMessage().contains(\"start of an array\")) {\n    // parser sits on an object/scalar — handle alternative shape\n    if (parser.currentTokenId() == com.fasterxml.jackson.core.JsonTokenId.ID_START_OBJECT) {\n      return java.util.List.of(JacksonCodec.parseObject(parser));\n    }\n  }\n  throw e;\n}","preventionTips":["Inspect the first non-whitespace character to choose array vs object decoding","Handle APIs that return a single object where an array is expected (wrap it)","Decode into Object and instanceof-check before casting to JsonArray","Add contract tests against real response shapes"],"tags":["json","decoding","type-mismatch","jackson"],"backgroundTag":"shape-mismatch","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"}