{"record":{"id":"77399e069e717304","repo":"apple/pkl","slug":"integeroverflow-77399e","errorCode":"integerOverflow","errorMessage":"integerOverflow","messagePattern":"integerOverflow","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/ast/expression/binary/SubtractionNode.java","lineNumber":36,"sourceCode":"import com.oracle.truffle.api.CompilerDirectives;\nimport com.oracle.truffle.api.dsl.Specialization;\nimport com.oracle.truffle.api.nodes.NodeInfo;\nimport com.oracle.truffle.api.source.SourceSection;\nimport org.pkl.core.runtime.*;\n\n@NodeInfo(shortName = \"-\")\npublic abstract class SubtractionNode extends BinaryExpressionNode {\n  protected SubtractionNode(SourceSection sourceSection) {\n    super(sourceSection);\n  }\n\n  @Specialization\n  protected long eval(long left, long right) {\n    try {\n      return StrictMath.subtractExact(left, right);\n    } catch (ArithmeticException e) {\n      CompilerDirectives.transferToInterpreter();\n      throw exceptionBuilder().evalError(\"integerOverflow\").build();\n    }\n  }\n\n  @Specialization\n  protected double eval(long left, double right) {\n    return left - right;\n  }\n\n  @Specialization\n  protected double eval(double left, long right) {\n    return left - right;\n  }\n\n  @Specialization\n  protected double eval(double left, double right) {\n    return left - right;\n  }\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/ast/expression/binary/SubtractionNode.java#L18-L54","documentation":"Thrown when subtracting two Pkl `Int` values overflows 64-bit signed range (StrictMath.subtractExact throws ArithmeticException). Pkl integers are fixed-size Longs, so results below Long.MIN_VALUE are rejected instead of silently wrapping.","triggerScenarios":"Evaluating `left - right` where the mathematical result is less than -9223372036854775808; e.g. subtracting a large positive from Long.MIN_VALUE, or accumulating large differences in a loop.","commonSituations":"Big-number arithmetic on config values (byte offsets, timestamps in nanoseconds), porting code that assumed arbitrary-precision or wrapped arithmetic.","solutions":["Perform the subtraction as `Float`/`Double` if exact integer precision is not required","Split the computation so intermediate values stay in range","Use `Int` values that fit in the 64-bit range; validate magnitudes before subtracting","Consider `IntSeq`/string-based big values or restructure to avoid extremes"],"exampleFix":"// before\nresult = bigInt - otherBigInt\n// after\nresult = bigInt.toDouble() - otherBigInt","handlingStrategy":"validation","validationCode":"function canSubtract(a, b) { return (a - b) >= -9223372036854775808n }","typeGuard":"function inInt64Range(x) { return x >= -9223372036854775808n && x <= 9223372036854775807n }","tryCatchPattern":null,"preventionTips":["Check magnitude of operands before large arithmetic","Use Float when results may exceed Int64","Avoid accumulating huge intermediate values"],"tags":["pkl","arithmetic","integer-overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}