{"record":{"id":"323bb092fa50379a","repo":"apple/pkl","slug":"stack-overflow","errorCode":null,"errorMessage":"Stack overflow","messagePattern":"Stack overflow","errorType":"console","errorClass":"VmException","httpStatus":null,"severity":"critical","filePath":"pkl-core/src/main/java/org/pkl/core/runtime/CommandSpecParser.java","lineNumber":1090,"sourceCode":"        && vmTyped.getVmClass() == CommandModule.getImportClass();\n  }\n\n  // handle errors from convert/transformAll and correctly format them for the CLI\n  private Object handleBadValue(Supplier<Object> f) {\n    try {\n      return handleErrors(f);\n    } catch (Throwable e) {\n      // add a newline so this prints nicely under \"Error: invalid value for <name>:\"\n      throw new BadValue(\"\\n\" + e.getMessage());\n    }\n  }\n\n  private <T> T handleErrors(Supplier<T> f) {\n    try {\n      return f.get();\n    } catch (VmStackOverflowException e) {\n      if (VmUtils.isPklBug(e)) {\n        throw new VmExceptionBuilder()\n            .bug(\"Stack overflow\")\n            .withCause(e.getCause())\n            .build()\n            .toPklException(frameTransformer, color);\n      }\n      throw e.toPklException(frameTransformer, color);\n    } catch (VmException e) {\n      throw e.toPklException(frameTransformer, color);\n    } catch (Exception e) {\n      throw new PklBugException(e);\n    }\n  }\n\n  // for convert, handle imports by replacing Command.Import values\n  // with imported module or Mapping<String, Module> values\n  // Command.Import instances in returned Pair, List, Set, or Map values are replaced as well\n  // other types or nested instances of the above are not affected\n  private Object handleImports(Object result, URI workingDirUri) {","sourceCodeStart":1072,"sourceCodeEnd":1108,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/runtime/CommandSpecParser.java#L1072-L1108","documentation":"When a command-spec value converter triggers a Pkl stack overflow, CommandSpecParser.handleErrors converts it: if VmUtils.isPklBug(e) says the overflow is a Pkl internal issue, it is re-thrown as a VmException with message 'Stack overflow' marked as a bug, attaching the original cause. Otherwise the exception is converted normally with its evaluation frames. Receiving the 'bug' variant means stack exhaustion occurred inside Pkl's own machinery rather than user recursion.","triggerScenarios":"A convert/transformAll function evaluated by the CLI engine recurses until VmStackOverflowException is raised, and the frames indicate a Pkl-internal defect (isPklBug true).","commonSituations":"Deeply recursive Pkl expressions evaluated during CLI value conversion; evaluator bugs in generators/collections that recurse infinitely; very large nested inputs to converters.","solutions":["Report this to the Pkl project as a bug; include the cause/stack trace attached to the VmException.","Reduce recursion depth in the Pkl code executed by the converter (rewrite recursion as fold/loop).","Increase the evaluation/stack limits only as a workaround; the error indicates an internal defect, not expected user error."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// bound recursion in Pkl code invoked by converters\nfun depth(n: Int, max: Int = 1000): Int = if (n >= max) max else depth(n + 1)","typeGuard":null,"tryCatchPattern":"try {\n  convert(value)\n} catch (e: StackOverflowError) {\n  throw IllegalArgumentException(\"input too deeply nested for converter\")\n}","preventionTips":["Rewrite recursive Pkl logic iteratively where possible","Report isPklBug=true stack overflows upstream with the cause chain","Keep converter inputs shallow and validate structure first"],"tags":["pkl","stack-overflow","internal-bug","recursion"],"backgroundTag":"internal-invariant-violation","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}