apple/pkl · error · ConversionException

Failed to convert `pkl.semver#Version` to `org.pkl.core.Vers

Error message

Failed to convert `pkl.semver#Version` to `org.pkl.core.Version`.

What it means

Thrown by the Conversions.pVersionToVersion conversion when mapping a Pkl `pkl.semver#Version` object to `org.pkl.core.Version`. The major/minor/patch components are read as Long values and converted via Math.toIntExact; if any component exceeds Integer.MAX_VALUE (or is otherwise out of int range), ArithmeticException is thrown and wrapped in a ConversionException.

Source

Thrown at pkl-config-java/src/main/java/org/pkl/config/java/mapper/Conversions.java:226

          PClassInfo.Duration, java.time.Duration.class, (value, mapper) -> value.toJavaDuration());

  /** Conversion from {@code pkl.semver#Version} to {@link Version}. */
  // Cannot leave this to `ConverterFactories.pObjectToDataObject`
  // because `Version` is part of pkl-core and thus cannot be annotated with `@Named`.
  public static final Conversion<PObject, Version> pVersionToVersion =
      Conversion.of(
          PClassInfo.Version,
          Version.class,
          (value, mapper) -> {
            try {
              return new Version(
                  Math.toIntExact((Long) value.getProperty("major")),
                  Math.toIntExact((Long) value.getProperty("minor")),
                  Math.toIntExact((Long) value.getProperty("patch")),
                  (String) value.get("preRelease"),
                  (String) value.get("build"));
            } catch (ArithmeticException e) {
              throw new ConversionException(
                  "Failed to convert `pkl.semver#Version` to `org.pkl.core.Version`.", e);
            }
          });

  public static final Conversion<PObject, String> pVersionToString =
      Conversion.of(
          PClassInfo.Version,
          String.class,
          (value, mapper) -> {
            var builder = new StringBuilder();
            builder.append(value.get("major"));
            builder.append('.');
            builder.append(value.get("minor"));
            builder.append('.');
            builder.append(value.get("patch"));
            var preRelease = value.get("preRelease");
            if (preRelease != null) {
              builder.append('-');

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Reduce the offending semver component in the Pkl config to a value that fits in a 32-bit signed integer (<= 2147483647).
  2. If huge components are genuinely needed, map the version to String (pVersionToString) and parse with a library supporting arbitrary-precision components.
  3. Pre-validate in Pkl or Java: check major/minor/patch against Int.MAX_VALUE before mapping.
  4. Audit where the large number comes from — often a concatenation bug (e.g. timestamp in wrong field) in the generating code.

Example fix

// before (pkl)
version = import("pkl").semver.Version(99999999999, 0, 0)
// after (pkl)
version = import("pkl").semver.Version(2147483647, 0, 0)
Defensive patterns

Strategy: validation

Validate before calling

if (version.get("major") instanceof Long m && (m > Integer.MAX_VALUE || m < 0)) throw new IllegalStateException("semver major does not fit in int: " + m); // same for minor/patch

Type guard

static boolean fitsJavaVersion(pkl.semver.Version v) { return v.get("major") instanceof Long a && a <= Integer.MAX_VALUE && a >= 0 && v.get("minor") instanceof Long b && b <= Integer.MAX_VALUE && v.get("patch") instanceof Long c && c <= Integer.MAX_VALUE; }

Try / catch

try { MyConfig cfg = mapper.map(module, MyConfig.class); } catch (ConversionException e) { throw new IllegalStateException("Semver component exceeds 32-bit range", e.getCause()); }

Prevention

When it happens

Trigger: A Pkl `pkl.semver#Version` whose `major`, `minor`, or `patch` property is greater than 2147483647 (semver allows arbitrarily large numeric components; Java Version stores them as ints), then mapping a module object to a Java target type with an `org.pkl.core.Version` field or invoking pVersionToVersion directly.

Common situations: Synthetic/test versions like `99999999999.0.0`; programmatically generated Pkl values where a build-number was put into major; dates-as-numbers (e.g. `20260908.0.0`) are fine, but values past 2^31 are not.

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