apple/pkl · error

divisionByZero

divisionByZero

Error message

divisionByZero

What it means

Runtime guard in TruncatingDivisionNode.eval: integer truncating division (`~/`) with a right operand of 0 raises the 'divisionByZero' eval error before the division executes, since long division by zero is undefined. The input at fault is a divisor expression evaluating to 0.

Solutions

  1. Check the divisor is non-zero before performing `~/`.
  2. Use a default value via the `??` operator on a guarded division.

Example fix

// before
ratio = total ~/ divisor
// after
ratio = if (divisor == 0) 0 else total ~/ divisor
Defensive patterns

Strategy: validation

Validate before calling

function safeTruncDiv(a, b) { return b === 0 ? 0 : a ~/ b }

Type guard

function isNonZero(n) { return typeof n === 'number' && n !== 0 }

Prevention

When it happens

Trigger: Evaluating `left ~/ right` where `right == 0`; e.g. a denominator computed from an empty sum, a defaulted config value of 0, or user-supplied divisor.

Common situations: Config values like `batchSize` or `scaleFactor` defaulting to 0, computing averages over zero-length collections.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/binary/TruncatingDivisionNode.java:39

import com.oracle.truffle.api.source.SourceSection;
import java.math.RoundingMode;
import org.pkl.core.runtime.VmDataSize;
import org.pkl.core.runtime.VmDuration;
import org.pkl.core.runtime.VmException.ProgramValue;
import org.pkl.core.util.MathUtils;

@NodeInfo(shortName = "~/")
@SuppressWarnings("SuspiciousNameCombination")
public abstract class TruncatingDivisionNode extends BinaryExpressionNode {
  protected TruncatingDivisionNode(SourceSection sourceSection) {
    super(sourceSection);
  }

  @Specialization
  protected long eval(long left, long right) {
    if (right == 0) {
      CompilerDirectives.transferToInterpreter();
      throw exceptionBuilder().evalError("divisionByZero").build();
    }

    var result = left / right;

    // use same check as com.oracle.truffle.sl.nodes.expression.SLDivNode
    if ((left & right & result) < 0) {
      CompilerDirectives.transferToInterpreter();
      assert left == Long.MIN_VALUE && right == -1;
      throw exceptionBuilder().evalError("integerOverflow").build();
    }
    return result;
  }

  @Specialization
  protected long eval(long left, double right) {
    return doTruncatingDivide(left, right);
  }

View on GitHub (pinned to f3efcbfc9b)