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 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.

Source

Thrown at vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/JacksonCodec.java:275

        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.nextName();
    if (key1 == null) {
      return new LinkedHashMap<>(2);
    }
    parser.nextToken();
    Object value1 = parseValue(parser);
    String key2 = parser.nextName();
    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

  1. Advance/position the parser to the object start token before calling parseObject (call parser.nextToken() so currentTokenId() == ID_START_OBJECT)
  2. Check the input shape first: if it starts with '[', call parseArray instead of parseObject
  3. Validate the payload is a JSON object before decoding (e.g. trimmed input starts with '{')

Example fix

// before
JsonParser p = mapper.createParser("[1,2]");
Map<String,Object> m = JacksonCodec.parseObject(p); // DecodeException
// after
JsonParser p = mapper.createParser("[1,2]");
if (p.nextToken() == JsonToken.START_ARRAY) {
  List<Object> l = JacksonCodec.parseArray(p);
} else {
  Map<String,Object> m = JacksonCodec.parseObject(p);
}
Defensive patterns

Strategy: type-guard

Validate before calling

String t = input.trim();
if (!t.startsWith("{")) throw new IllegalArgumentException("expected a JSON object");

Type guard

static boolean isJsonObjectToken(JsonParser p) {
  return p.currentTokenId() == JsonTokenId.ID_START_OBJECT;
}

Try / catch

try {
  Map<String,Object> m = JacksonCodec.parseObject(parser);
} catch (DecodeException e) {
  // parser not positioned on START_OBJECT — inspect token and dispatch
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/56415afe23cd6c06. Report an issue: GitHub.