apple/pkl · error · FormatException

FormatException(key, "integer", ret.getClass())

Error message

FormatException(key, "integer", ret.getClass())

What it means

Thrown by JsObject.getInt(String) when the JSON field with the given key exists but holds a value that is not an Integer (e.g. a String, Double, Boolean, or nested object). The pkl JSON parser maps whole numbers to Integer, so any other Java type under that key fails the instanceof check. The FormatException names the key, the expected type 'integer', and the actual class to pinpoint the mismatch.

Source

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

    public boolean getBoolean(String key) throws JsonParseException {
      var ret = get(key);
      if (ret == null) {
        throw new MissingFieldException(this, key);
      }
      if (!(ret instanceof Boolean b)) {
        throw new FormatException(key, "boolean", ret.getClass());
      }
      return b;
    }

    public int getInt(String key) throws JsonParseException {
      var ret = get(key);
      if (ret == null) {
        throw new MissingFieldException(this, key);
      }
      if (!(ret instanceof Integer i)) {
        throw new FormatException(key, "integer", ret.getClass());
      }
      return i;
    }

    public String getString(String key) throws JsonParseException {
      var ret = getStringOrNull(key);
      if (ret == null) {
        throw new MissingFieldException(this, key);
      }
      return ret;
    }

    public @Nullable String getStringOrNull(String key) throws JsonParseException {
      var ret = get(key);
      if (ret == null) {
        return null;
      }
      if (!(ret instanceof String string)) {

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Print the actual value type for the key (get(key).getClass()) and confirm what the JSON really contains
  2. Read the field with getString + parse, or a numeric helper matching the real type (e.g. parse the string via Integer.parseInt)
  3. Fix the producing side so the field is emitted as an unquoted whole number
  4. Add a validation step before calling getInt that checks ret instanceof Integer

Example fix

// before: {"major": "3"}  -> obj.getInt("major") throws
// after: {"major": 3}
// or in code:
// before
int major = obj.getInt("major");
// after
int major = obj.getString("major") != null ? Integer.parseInt(obj.getString("major")) : obj.getInt("major");
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = obj.get("major");
if (!(v instanceof Integer)) throw new IllegalStateException("field 'major' must be a whole number, got " + (v == null ? "null" : v.getClass().getSimpleName()));

Type guard

boolean isIntField(JsObject o, String k) { return o.get(k) instanceof Integer; }

Try / catch

try { int n = obj.getInt("major"); } catch (JsonParseException e) { /* log key/type mismatch, use default */ }

Prevention

When it happens

Trigger: Calling getInt(key) on a JsObject whose value for key parsed as a JSON string, floating-point number, boolean, array, or object instead of a whole-number JSON literal (e.g. {"major":"3"} or {"count":3.5}).

Common situations: A JSON document produced by another tool encodes numeric fields as strings; a schema change upstream switched a version/limit field from an integer to a decimal or string; hand-edited config quotes the number.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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