apple/pkl · critical · VmException

Stack overflow

Error message

Stack overflow

What it means

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.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/runtime/CommandSpecParser.java:1090

        && vmTyped.getVmClass() == CommandModule.getImportClass();
  }

  // handle errors from convert/transformAll and correctly format them for the CLI
  private Object handleBadValue(Supplier<Object> f) {
    try {
      return handleErrors(f);
    } catch (Throwable e) {
      // add a newline so this prints nicely under "Error: invalid value for <name>:"
      throw new BadValue("\n" + e.getMessage());
    }
  }

  private <T> T handleErrors(Supplier<T> f) {
    try {
      return f.get();
    } catch (VmStackOverflowException e) {
      if (VmUtils.isPklBug(e)) {
        throw new VmExceptionBuilder()
            .bug("Stack overflow")
            .withCause(e.getCause())
            .build()
            .toPklException(frameTransformer, color);
      }
      throw e.toPklException(frameTransformer, color);
    } catch (VmException e) {
      throw e.toPklException(frameTransformer, color);
    } catch (Exception e) {
      throw new PklBugException(e);
    }
  }

  // for convert, handle imports by replacing Command.Import values
  // with imported module or Mapping<String, Module> values
  // Command.Import instances in returned Pair, List, Set, or Map values are replaced as well
  // other types or nested instances of the above are not affected
  private Object handleImports(Object result, URI workingDirUri) {

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Report this to the Pkl project as a bug; include the cause/stack trace attached to the VmException.
  2. Reduce recursion depth in the Pkl code executed by the converter (rewrite recursion as fold/loop).
  3. Increase the evaluation/stack limits only as a workaround; the error indicates an internal defect, not expected user error.
Defensive patterns

Strategy: try-catch

Validate before calling

// bound recursion in Pkl code invoked by converters
fun depth(n: Int, max: Int = 1000): Int = if (n >= max) max else depth(n + 1)

Try / catch

try {
  convert(value)
} catch (e: StackOverflowError) {
  throw IllegalArgumentException("input too deeply nested for converter")
}

Prevention

When it happens

Trigger: A convert/transformAll function evaluated by the CLI engine recurses until VmStackOverflowException is raised, and the frames indicate a Pkl-internal defect (isPklBug true).

Common situations: Deeply recursive Pkl expressions evaluated during CLI value conversion; evaluator bugs in generators/collections that recurse infinitely; very large nested inputs to converters.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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