{"record":{"id":"bbf211753ce7e82f","repo":"apple/pkl","slug":"formatexception-key-boolean-ret-getclass","errorCode":null,"errorMessage":"FormatException(key, \"boolean\", ret.getClass())","messagePattern":"FormatException\\(key, \"boolean\", ret\\.getClass\\(\\)\\)","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/json/Json.java","lineNumber":257,"sourceCode":"        throw new MappingException(key, e);\n      }\n    }\n\n    public <T> @Nullable T getNullable(String key, Mapper<T> mapper) throws JsonParseException {\n      var ret = get(key);\n      if (ret == null) {\n        return null;\n      }\n      return get(key, mapper);\n    }\n\n    public boolean getBoolean(String key) throws JsonParseException {\n      var ret = get(key);\n      if (ret == null) {\n        throw new MissingFieldException(this, key);\n      }\n      if (!(ret instanceof Boolean b)) {\n        throw new FormatException(key, \"boolean\", ret.getClass());\n      }\n      return b;\n    }\n\n    public int getInt(String key) throws JsonParseException {\n      var ret = get(key);\n      if (ret == null) {\n        throw new MissingFieldException(this, key);\n      }\n      if (!(ret instanceof Integer i)) {\n        throw new FormatException(key, \"integer\", ret.getClass());\n      }\n      return i;\n    }\n\n    public String getString(String key) throws JsonParseException {\n      var ret = getStringOrNull(key);\n      if (ret == null) {","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/json/Json.java#L239-L275","documentation":"JsObject.getBoolean(key) throws FormatException when the key exists but its value is not a JSON boolean (e.g. the string \"true\", the number 1, or an object). The exception records the expected type \"boolean\" and the actual value class.","triggerScenarios":"Calling getBoolean on a field holding a non-boolean JSON type, e.g. {\"enabled\": \"true\"} or {\"enabled\": 1}.","commonSituations":"Producers encoding booleans as strings/ints; YAML-derived or legacy JSON where 0/1 represent booleans; schema drift after API changes.","solutions":["Fix the producer to emit real JSON booleans (true/false).","Read with a lenient mapper (e.g. map \"true\"/1 to Boolean yourself) via get(key, mapper).","Validate the payload against a schema before extraction."],"exampleFix":"// before\nboolean enabled = obj.getBoolean(\"enabled\"); // value: \"true\"\n// after\nboolean enabled = obj.get(\"enabled\", v ->\n    v instanceof Boolean b ? b : Boolean.parseBoolean(((JsString) v).value()));","handlingStrategy":"type-guard","validationCode":"Object v = obj.getNullable(\"enabled\", Function.identity());\nif (!(v instanceof Boolean)) throw new IllegalArgumentException(\"'enabled' must be a JSON boolean, got: \" + (v == null ? \"null\" : v.getClass()));","typeGuard":"Object v = obj.getNullable(\"enabled\", Function.identity());\nboolean enabled = v instanceof Boolean b ? b : (v instanceof JsString s ? Boolean.parseBoolean(s.value()) : false);","tryCatchPattern":"try {\n  boolean enabled = obj.getBoolean(\"enabled\");\n} catch (Json.FormatException e) {\n  // value present but wrong type; coerce or fail with context\n}","preventionTips":["Reject string-encoded booleans (\"true\"/\"false\") at ingestion.","Run JSON schema validation with type constraints before extraction.","Pin producer output to a contract test so types don't drift."],"tags":["json","type-mismatch","parsing"],"backgroundTag":"type-mismatch","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"}