apple/pkl · error

cannotConvertLargeFloat

Error message

cannotConvertLargeFloat

What it means

FloatNodes' round-to-long specialization (Float.prototype.round with DOWN/ truncate-style semantics) converts a double to a long via MathUtils.roundToLong, which throws ArithmeticException when the value exceeds long range. Pkl then throws `cannotConvertLargeFloat` for finite out-of-range floats (or `cannotConvertNonFiniteFloat` for NaN/Infinity), embedding the offending value as a ProgramValue.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/FloatNodes.java:214

      return StrictMath.rint(self);
    }
  }

  public abstract static class truncate extends ExternalMethod0Node {
    @Specialization
    protected double eval(double self) {
      return VmSafeMath.truncate(self);
    }
  }

  public abstract static class toInt extends ExternalMethod0Node {
    @Specialization
    protected long eval(double self) {
      try {
        return MathUtils.roundToLong(self, RoundingMode.DOWN);
      } catch (ArithmeticException e) {
        CompilerDirectives.transferToInterpreter();
        throw exceptionBuilder()
            .evalError(
                Double.isFinite(self) ? "cannotConvertLargeFloat" : "cannotConvertNonFiniteFloat",
                new ProgramValue("Float", self))
            .build();
      }
    }
  }

  public abstract static class toFloat extends ExternalMethod0Node {
    @Specialization
    protected double eval(double self) {
      return self;
    }
  }

  public abstract static class toString extends ExternalMethod0Node {
    @Specialization
    @TruffleBoundary

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Range-check the float (`v >= -9.22e18 && v <= 9.22e18`) before converting to Int.
  2. Work with Int arithmetic instead of Float if the values are inherently integral.
  3. Clamp or rescale the computation producing the huge float.
  4. Handle non-finite values separately (check `v.isFinite()`) before rounding.

Example fix

// before
i = 1e20.round()  // cannotConvertLargeFloat
// after
i = if (v.isFinite() && v.abs() < 9.22e18) v.round() else throw("value too large")
Defensive patterns

Strategy: validation

Validate before calling

function roundableToInt(v) {
  return v.isFinite && v >= -9223372036854775808 && v <= 9223372036854775807;
}

Type guard

function isSafeInt(v) {
  return typeof v === "number" && Number.isFinite(v) && Math.abs(v) < 9.22e18;
}

Prevention

When it happens

Trigger: Calling `.round(...)`/integer truncation on a double whose magnitude exceeds Long.MAX_VALUE (~9.22e18), e.g. `1e20.round()` or `(1.0/0.0)` — thrown at FloatNodes.java:214 when MathUtils.roundToLong raises ArithmeticException and Double.isFinite(self) is true.

Common situations: Unbounded float math (exponentiation, products of large values) feeding into integer conversion, or computed values from user config that were assumed to stay small.

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/e405dd56590a56f0. Report an issue: GitHub.