apple/pkl · error · FormatException

object

Error message

object

What it means

Json.parseObject validates that the parsed JSON top-level value is a JSON object; if the document parsed successfully but is an array, string, number, boolean, null, or nothing, a FormatException with message "object" is thrown indicating an unexpected top-level type.

Solutions

  1. Check the document's root type before parsing (use a generic parse and inspect instanceof JsObject).
  2. Fix the data source or endpoint to return a JSON object (wrap the array: {"items": [...]}).
  3. Use the correct parse method for arrays/other roots instead of parseObject.

Example fix

// before
JsObject obj = Json.parseObject("[1,2,3]");
// after
Object root = Json.parse("[1,2,3]");
if (root instanceof JsObject obj) { ... }
Defensive patterns

Strategy: type-guard

Validate before calling

if (!json.trim().startsWith("{")) throw new IllegalArgumentException("expected a JSON object at root");

Type guard

Object root = Json.parse(input);
if (!(root instanceof JsObject obj)) throw new IllegalArgumentException("root is not a JSON object: " + (root == null ? "null" : root.getClass()));

Try / catch

try {
  JsObject obj = Json.parseObject(input);
} catch (Json.JsonParseException e) {
  // handle non-object root / malformed json
}

Prevention

When it happens

Trigger: Calling Json.parseObject on JSON whose root is not an object, e.g. parsing "[1,2,3]" or "null" or an empty stream with parseObject instead of a variant that handles other roots.

Common situations: APIs that sometimes return a bare array or an error string; JSONL/fragment files where the top level is a list; endpoints returning null on empty results.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/5092aa250b70f4f4. Report an issue: GitHub.

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/util/json/Json.java:88

@SuppressWarnings("unused")
public final class Json {
  @FunctionalInterface
  public interface Mapper<R> {
    R apply(Object arg) throws Exception;
  }

  /** Parses {@code input}, expecting it to be a JSON object. */
  public static JsObject parseObject(String input) throws JsonParseException {
    var handler = new Handler();
    var parser = new JsonParser(handler);
    try {
      parser.parse(input);
    } catch (ParseException e) {
      throw new MalformedJsonException(e, input);
    }
    var ret = handler.value;
    if (!(ret instanceof JsObject jsObject)) {
      throw new FormatException("object", ret == null ? Void.class : ret.getClass());
    }
    return jsObject;
  }

  public abstract static class JsonParseException extends Exception {}

  public static class MalformedJsonException extends JsonParseException {

    private final String message;

    public MalformedJsonException(ParseException e, String inputString) {
      this.message = ErrorMessages.create("malformedJson", e.getMessage(), inputString);
      initCause(e);
    }

    @Override
    public String getMessage() {
      return message;

View on GitHub (pinned to f3efcbfc9b)