apple/pkl · error · ParseException

Nesting too deep

Error message

Nesting too deep

What it means

Pkl's JSON parser enforces MAX_NESTING_LEVEL on arrays (and objects): when the nesting level of nested `[` exceeds the maximum, parsing aborts with 'Nesting too deep'. This guards both the parser and the Truffle interpreter against stack exhaustion from hostile or accidental deeply nested JSON.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/util/json/JsonParser.java:147

  private void readValue() throws IOException {
    switch (current) {
      case 'n' -> readNull();
      case 't' -> readTrue();
      case 'f' -> readFalse();
      case '"' -> readString();
      case '[' -> readArray();
      case '{' -> readObject();
      case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> readNumber();
      default -> throw expected("value");
    }
  }

  private void readArray() throws IOException {
    var array = handler.startArray();
    read();
    if (++nestingLevel > MAX_NESTING_LEVEL) {
      throw error("Nesting too deep");
    }
    skipWhiteSpace();
    if (readChar(']')) {
      nestingLevel--;
      handler.endArray(array);
      return;
    }
    do {
      skipWhiteSpace();
      handler.startArrayValue(array);
      readValue();
      handler.endArrayValue(array);
      skipWhiteSpace();
    } while (readChar(','));
    if (!readChar(']')) {
      throw expected("',' or ']'");
    }
    nestingLevel--;

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Flatten or restructure the data before serializing/parsing (avoid encoding recursion as nesting)
  2. Increase/patch the MAX_NESTING_LEVEL constant if your legitimate data is deeply nested (library rebuild)
  3. Reject overly deep input upstream with a quick depth check before parsing
  4. Fix the producer bug that serializes cyclic/recursive structures as unbounded nesting

Example fix

// before
val = json.parse(deepNestedJson)  // 1000 levels
// after
assert(depth(deepNestedJson) < 100)
val = json.parse(deepNestedJson)
Defensive patterns

Strategy: validation

Validate before calling

// cheap depth check on brackets before parsing
depth = 0; max = 0
text.chars.forEach((c) -> {
  if (c == '[' || c == '{') { depth++; max = Math.max(max, depth) }
  else if (c == ']' || c == '}') depth--
})
require(max < 100, "JSON nesting too deep")

Try / catch

try {
  value = json.parse(text)
} catch (e) {
  if (e.message.contains("Nesting too deep")) throw("rejecting overly deep JSON input")
  throw e
}

Prevention

When it happens

Trigger: Calling `json.parse` on a document with arrays nested beyond MAX_NESTING_LEVEL, e.g. `[[[[[...]]]]]` generated recursively or by adversarial input. Raised in JsonParser.readArray immediately after incrementing nestingLevel.

Common situations: Parsing auto-generated JSON from recursive data structures (linked lists encoded as nested arrays); fuzzed or malicious payloads; runaway serialization bugs producing self-nesting output.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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