{"record":{"id":"6fbd2ea0c38a3f2a","repo":"apple/pkl","slug":"divisionbyzero","errorCode":"divisionByZero","errorMessage":"divisionByZero","messagePattern":"divisionByZero","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/ast/expression/binary/TruncatingDivisionNode.java","lineNumber":39,"sourceCode":"import com.oracle.truffle.api.source.SourceSection;\nimport java.math.RoundingMode;\nimport org.pkl.core.runtime.VmDataSize;\nimport org.pkl.core.runtime.VmDuration;\nimport org.pkl.core.runtime.VmException.ProgramValue;\nimport org.pkl.core.util.MathUtils;\n\n@NodeInfo(shortName = \"~/\")\n@SuppressWarnings(\"SuspiciousNameCombination\")\npublic abstract class TruncatingDivisionNode extends BinaryExpressionNode {\n  protected TruncatingDivisionNode(SourceSection sourceSection) {\n    super(sourceSection);\n  }\n\n  @Specialization\n  protected long eval(long left, long right) {\n    if (right == 0) {\n      CompilerDirectives.transferToInterpreter();\n      throw exceptionBuilder().evalError(\"divisionByZero\").build();\n    }\n\n    var result = left / right;\n\n    // use same check as com.oracle.truffle.sl.nodes.expression.SLDivNode\n    if ((left & right & result) < 0) {\n      CompilerDirectives.transferToInterpreter();\n      assert left == Long.MIN_VALUE && right == -1;\n      throw exceptionBuilder().evalError(\"integerOverflow\").build();\n    }\n    return result;\n  }\n\n  @Specialization\n  protected long eval(long left, double right) {\n    return doTruncatingDivide(left, right);\n  }\n","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/ast/expression/binary/TruncatingDivisionNode.java#L21-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"Config values like `batchSize` or `scaleFactor` defaulting to 0, computing averages over zero-length collections.","solutions":["Check the divisor is non-zero before performing `~/`.","Use a default value via the `??` operator on a guarded division."],"exampleFix":"// before\nratio = total ~/ divisor\n// after\nratio = if (divisor == 0) 0 else total ~/ divisor","handlingStrategy":"validation","validationCode":"function safeTruncDiv(a, b) { return b === 0 ? 0 : a ~/ b }","typeGuard":"function isNonZero(n) { return typeof n === 'number' && n !== 0 }","tryCatchPattern":null,"preventionTips":["Validate divisor config values with `> 0` constraints","Provide non-zero defaults for denominators","Check before dividing in loops"],"tags":["pkl","division-by-zero","arithmetic"],"backgroundTag":"invalid-argument-value","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}