apple/pkl · error · FormatException

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

Error message

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

What it means

Thrown by JsObject.getArray(String) when the key is present but the value is not a JSON array (e.g. a string, number, or object). The FormatException names the key, the expected type 'array', and the actual value class.

Source

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

    public JsObject getObject(String key) throws JsonParseException {
      var ret = get(key);
      if (ret == null) {
        throw new MissingFieldException(this, key);
      }
      if (!(ret instanceof JsObject jsObject)) {
        throw new FormatException(key, "object", ret.getClass());
      }
      return jsObject;
    }

    public JsArray getArray(String key) throws JsonParseException {
      var ret = get(key);
      if (ret == null) {
        throw new MissingFieldException(this, key);
      }
      if (!(ret instanceof JsArray jsArray)) {
        throw new FormatException(key, "array", ret.getClass());
      }
      return jsArray;
    }

    public Version getVersion(String key) throws JsonParseException {
      var versionStr = getString(key);
      try {
        return Version.parse(versionStr);
      } catch (IllegalArgumentException e) {
        throw new MappingException(key, e);
      }
    }

    public URI getURI(String key) throws JsonParseException {
      var result = getURIOrNull(key);
      if (result == null) {
        throw new MissingFieldException(this, key);
      }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Inspect the value's real type with get(key).getClass()
  2. Use the appropriate getter for the actual type or normalize single values into a list
  3. Fix the producer to emit a JSON array
  4. Pre-validate with instanceof before calling

Example fix

// before: {"exports": "all"} -> obj.getArray("exports") throws
// after: {"exports": ["all"]}
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = obj.get("exports");
if (!(v instanceof JsArray)) throw new IllegalStateException("field 'exports' must be a JSON array, got " + (v == null ? "null" : v.getClass().getSimpleName()));

Type guard

boolean isArrayField(JsObject o, String k) { return o.get(k) instanceof JsArray; }

Try / catch

try { JsArray a = obj.getArray("exports"); } catch (JsonParseException e) { /* normalize scalar to single-element list */ }

Prevention

When it happens

Trigger: Calling getArray(key) where the JSON value under key is a scalar or object, e.g. {"exports": "all"} instead of {"exports": ["all"]}.

Common situations: Schema change turned an array field into a scalar for single-element cases; producer bug; hand-edited JSON dropping the brackets.

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/e8a0d7697e861de3. Report an issue: GitHub.