{"record":{"id":"5092aa250b70f4f4","repo":"apple/pkl","slug":"object-5092aa","errorCode":null,"errorMessage":"object","messagePattern":"object","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/json/Json.java","lineNumber":88,"sourceCode":"@SuppressWarnings(\"unused\")\npublic final class Json {\n  @FunctionalInterface\n  public interface Mapper<R> {\n    R apply(Object arg) throws Exception;\n  }\n\n  /** Parses {@code input}, expecting it to be a JSON object. */\n  public static JsObject parseObject(String input) throws JsonParseException {\n    var handler = new Handler();\n    var parser = new JsonParser(handler);\n    try {\n      parser.parse(input);\n    } catch (ParseException e) {\n      throw new MalformedJsonException(e, input);\n    }\n    var ret = handler.value;\n    if (!(ret instanceof JsObject jsObject)) {\n      throw new FormatException(\"object\", ret == null ? Void.class : ret.getClass());\n    }\n    return jsObject;\n  }\n\n  public abstract static class JsonParseException extends Exception {}\n\n  public static class MalformedJsonException extends JsonParseException {\n\n    private final String message;\n\n    public MalformedJsonException(ParseException e, String inputString) {\n      this.message = ErrorMessages.create(\"malformedJson\", e.getMessage(), inputString);\n      initCause(e);\n    }\n\n    @Override\n    public String getMessage() {\n      return message;","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/json/Json.java#L70-L106","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the document's root type before parsing (use a generic parse and inspect instanceof JsObject).","Fix the data source or endpoint to return a JSON object (wrap the array: {\"items\": [...]}).","Use the correct parse method for arrays/other roots instead of parseObject."],"exampleFix":"// before\nJsObject obj = Json.parseObject(\"[1,2,3]\");\n// after\nObject root = Json.parse(\"[1,2,3]\");\nif (root instanceof JsObject obj) { ... }","handlingStrategy":"type-guard","validationCode":"if (!json.trim().startsWith(\"{\")) throw new IllegalArgumentException(\"expected a JSON object at root\");","typeGuard":"Object root = Json.parse(input);\nif (!(root instanceof JsObject obj)) throw new IllegalArgumentException(\"root is not a JSON object: \" + (root == null ? \"null\" : root.getClass()));","tryCatchPattern":"try {\n  JsObject obj = Json.parseObject(input);\n} catch (Json.JsonParseException e) {\n  // handle non-object root / malformed json\n}","preventionTips":["Inspect the document's first non-whitespace character before choosing the parser.","Handle endpoints that may return arrays or null at the root.","Prefer a generic parse + instanceof narrowing over type-specific parse methods for heterogeneous sources."],"tags":["json","parsing","type-mismatch"],"backgroundTag":"unexpected-response-shape","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}