apple/pkl · error · ArithmeticException

Cannot convert Pkl duration `this` to `java.time.Duration`.

Error message

Cannot convert Pkl duration `this` to `java.time.Duration`.

What it means

Pkl's Duration.toJavaDuration() converts the duration value to java.time.Duration, but java.time.Duration cannot represent NaN or +/-Infinity seconds. When the Pkl duration's value is non-finite, an ArithmeticException is thrown with the message naming this Pkl duration.

Solutions

  1. Check Double.isFinite(duration.value) before calling toJavaDuration().
  2. Fix the upstream Pkl expression producing the non-finite duration.
  3. Clamp or substitute a finite sentinel duration before converting.

Example fix

// before
var d = pklDuration.toJavaDuration();
// after
if (Double.isFinite(pklDuration.value)) {
  var d = pklDuration.toJavaDuration();
} else {
  var d = Duration.ZERO; // or handle explicitly
}
Defensive patterns

Strategy: validation

Validate before calling

if (!Double.isFinite(pklDuration.value)) throw new ArithmeticException("non-finite duration");

Type guard

static boolean isConvertible(Duration d) { return Double.isFinite(d.value); }

Try / catch

try { return pklDuration.toJavaDuration(); } catch (ArithmeticException e) { return Duration.ZERO; /* or propagate */ }

Prevention

When it happens

Trigger: Calling toJavaDuration() on a Pkl duration whose value is NaN, +Infinity, or -Infinity (e.g. produced from 1/0-style arithmetic or from a Pkl `Infinity*min` expression).

Common situations: Pkl computed durations involving division by zero; durations imported from configs with extreme values; tests exercising edge cases of duration conversion.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/Duration.java:165

  /** Returns the value of this duration measured in whole {@link DurationUnit#HOURS}. */
  public long inWholeHours() {
    return Math.round(inHours());
  }

  /** Returns the value of this duration measured in whole {@link DurationUnit#DAYS}. */
  public long inWholeDays() {
    return Math.round(inDays());
  }

  /**
   * Converts this duration to a {@link java.time.Duration}. If {@link #getValue()} is NaN,
   * +/-Infinity or too large to fit into {@link java.time.Duration}, {@link ArithmeticException} is
   * thrown.
   */
  public java.time.Duration toJavaDuration() {
    if (!Double.isFinite(value)) {
      throw new ArithmeticException(
          "Cannot convert Pkl duration `" + this + "` to `java.time.Duration`.");
    }

    var l = (long) value;
    if (l == value) {
      // `value` is a mathematical integer that fits into a long.
      // Hence this duration is easy to convert without risk of rounding errors.
      // Throws ArithmeticException if this duration doesn't fit into java.time.Duration (e.g.,
      // Long.MAX_VALUE days).
      return java.time.Duration.of(l, unit.toChronoUnit());
    }

    var seconds = convertValueTo(DurationUnit.SECONDS);
    var secondsPart = (long) seconds;
    var nanosPart = (long) ((seconds - secondsPart) * 1_000_000_000);
    // If `seconds` is infinite or too large to fit into java.time.Duration,
    // this throws ArithmeticException because one the following holds:
    //   secondsPart == Long.MAX_VALUE && nanosPart >= 1_000_000_000

View on GitHub (pinned to f3efcbfc9b)