apple/pkl · error · VmException
divisionByZero
divisionByZero
Error message
divisionByZero
What it means
Pkl's truncating integer division (`~/`) throws `divisionByZero` when the divisor is 0. VmSafeMath.truncatingDivide performs an explicit zero check (rather than relying on catching ArithmeticException, which is unreliable in GraalVM AOT mode) and raises this eval error.
Solutions
- Guard the divisor: only divide when `y != 0`, else use a fallback value.
- Fix the upstream value so the denominator is nonzero (correct the config or default).
- For percentages/averages, special-case zero totals explicitly.
- Use a null/absent marker for undefined ratios instead of dividing by a zero placeholder.
Example fix
// before pct = used * 100 ~/ total // total may be 0 // after pct = if (total == 0) 0 else used * 100 ~/ total
Defensive patterns
Strategy: validation
Validate before calling
// Pkl safeDiv = (x: Int, y: Int) -> if (y == 0) 0 else x ~/ y
Type guard
function isNonZeroDivisor(y: Int): Boolean = y != 0
Prevention
- Always guard `~/` with a zero check on the divisor
- Validate externally supplied divisors before use
- Special-case zero totals for ratios and averages
- Avoid zero placeholders for 'unknown' values
When it happens
Trigger: Evaluating the `~/` Int division operator with a right-hand side that evaluates to 0 — commonly a computed denominator from config, a default `0` property, or an empty-collection-derived count.
Common situations: Computing ratios/averages where a totals property is 0 (e.g. percent = part * 100 ~/ total with total = 0); divisor read from external config/env that defaulted to 0.
Related errors
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/6dc0ff691f68fa6b.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-core/src/main/java/org/pkl/core/runtime/VmSafeMath.java:77
public static long multiply(long x, long y) {
try {
return StrictMath.multiplyExact(x, y);
} catch (ArithmeticException e) {
CompilerDirectives.transferToInterpreter();
throw intOverflow();
}
}
public static double multiply(double x, double y) {
return x * y;
}
public static long truncatingDivide(long x, long y) {
// for some reason, detecting division by zero by catching ArithmeticException
// does not work correctly in AOT mode, so let's do an explicit check for now
if (y == 0) {
CompilerDirectives.transferToInterpreter();
throw divisionByZero();
}
var result = x / y;
if ((x & y & result)
< 0) { // use same check as com.oracle.truffle.sl.nodes.expression.SLDivNode
CompilerDirectives.transferToInterpreter();
assert x == Long.MIN_VALUE && y == -1;
throw intOverflow();
}
return result;
}
public static long remainder(long x, long y) {
return x % y;
}
View on GitHub (pinned to f3efcbfc9b)