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
- Flatten or restructure the data before serializing/parsing (avoid encoding recursion as nesting)
- Increase/patch the MAX_NESTING_LEVEL constant if your legitimate data is deeply nested (library rebuild)
- Reject overly deep input upstream with a quick depth check before parsing
- 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
- Bound the nesting depth of serialized data at the producer
- Sanitize untrusted JSON with a depth limit before parsing
- Refactor recursive structures into flat, referenced forms
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.