apple/pkl · error · ArithmeticException
Cannot convert Pkl duration `${duration}` to ISO 8601 durati
Error message
Cannot convert Pkl duration `${duration}` to ISO 8601 duration. What it means
DurationUtils.toIsoString converts a Pkl duration (value + unit) to an ISO 8601 duration string. If the computed total number of seconds is not finite (NaN or Infinity, e.g. from overflow of very large values), the conversion is impossible and an ArithmeticException is thrown.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/util/DurationUtils.java:33
*/
package org.pkl.core.util;
import org.pkl.core.DurationUnit;
public final class DurationUtils {
private DurationUtils() {}
public static String toPklString(double value, DurationUnit unit) {
return MathUtils.isMathematicalInteger(value) ? (long) value + "." + unit : value + "." + unit;
}
// see: https://standards.calconnect.org/csd/cc-18011.html#toc32
public static String toIsoString(double value, DurationUnit unit) {
// different rounding behavior from `VmDuration.convertValueTo()`
var totalSeconds = value * (unit.getNanos() / 1e9);
if (!Double.isFinite(totalSeconds)) {
throw new ArithmeticException(
"Cannot convert Pkl duration `"
+ DurationUtils.toPklString(value, unit)
+ "` to ISO 8601 duration.");
}
var absoluteSeconds = Math.abs(totalSeconds);
var hours = (long) (absoluteSeconds / 3600);
var minutes = (long) (absoluteSeconds / 60) % 60;
var seconds = (long) (absoluteSeconds % 60);
var nanos =
(long) (absoluteSeconds * 1_000_000_000 - Math.floor(absoluteSeconds) * 1_000_000_000);
var builder = new StringBuilder();
if (totalSeconds < 0.0) {
builder.append('-');
}
View on GitHub (pinned to f3efcbfc9b)
Solutions
- Check the duration value is finite and within a sane range before calling toIsoString.
- Fix the upstream computation that produced NaN/Infinity.
- Clamp or split extremely large durations into finite second totals before conversion.
Example fix
// before
var iso = DurationUtils.toIsoString(hugeValue, DurationUnit.HOURS);
// after
if (Double.isFinite(hugeValue) && hugeValue < 1e15) {
var iso = DurationUtils.toIsoString(hugeValue, DurationUnit.HOURS);
} Defensive patterns
Strategy: validation
Validate before calling
if (!Double.isFinite(value)) throw new IllegalArgumentException("duration value must be finite");
Try / catch
try { return DurationUtils.toIsoString(value, unit); } catch (ArithmeticException e) { log.warn("non-finite duration: {}", e.getMessage()); return null; }
Prevention
- Bound-check duration values before conversion.
- Fix upstream math that can divide by zero or overflow.
- Test conversions with extreme values.
When it happens
Trigger: Calling toIsoString with a value so large that value * (unit.getNanos()/1e9) overflows to Double.POSITIVE_INFINITY/NEGATIVE_INFINITY, or a value/unit combination yielding NaN.
Common situations: Passing absurdly large duration values (e.g. huge hours/day counts in Float units); a computation upstream produced Infinity (division by zero duration) before conversion; parsing user input without bounds.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
Related errors
- Values of type `Duration` cannot be rendered as YAML. Value:
- Invalid Duration unit symbol:
- cannotRenderType
- Invalid Duration unit `%s`
- integerOverflow
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/a76b73a1adde20b1.
Report an issue: GitHub.