apple/pkl · error · VmException

cannotRenderValue

cannotRenderValue

Error message

cannotRenderValue

What it means

JSON has no representation for NaN or Infinity, so JsonRendererNodes' visitFloat throws cannotRenderValue when a Double value being rendered is NaN or infinite. The offending value and renderer name are attached to the error. All other floats render normally as JSON numbers.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/JsonRendererNodes.java:96

    }

    /** Use same escaping strategy as {@link org.pkl.core.util.json.JsonWriter}. */
    @Override
    public void visitString(String value) {
      builder.append('"');
      escaper.escape(value, builder);
      builder.append('"');
    }

    @Override
    public void visitInt(Long value) {
      builder.append((long) value);
    }

    @Override
    public void visitFloat(Double value) {
      if (value.isNaN() || value.isInfinite()) {
        throw new VmExceptionBuilder().evalError("cannotRenderValue", value, name).build();
      }
      builder.append((double) value);
    }

    @Override
    public void visitBoolean(Boolean value) {
      builder.append((boolean) value);
    }

    @Override
    public void visitNull(VmNull value) {
      builder.append("null");
    }

    @Override
    public void visitRenderDirective(VmTyped value) {
      // append verbatim
      builder.append(VmUtils.readTextProperty(value));

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Fix the computation producing NaN/Infinity (check for division by zero or invalid inputs).
  2. Replace NaN/Infinity values with a JSON-safe sentinel such as null or a string (e.g. `"Infinity"`) before rendering.
  3. Guard with `value.isNaN || value.isInfinite` and substitute a default.
  4. Render with a different format (e.g. YAML, which supports .inf/.nan) if the values are intentional.

Example fix

// before
output { ratio = 1.0 / 0.0 } // Infinity -> cannotRenderValue

// after
output { ratio = if (denom == 0.0) null else numer / denom }
Defensive patterns

Strategy: validation

Validate before calling

// replace non-JSON-safe floats before rendering
function jsonSafe(v: Number) = if (v.isNaN || v.isInfinite) null else v

Type guard

function isJsonSafeFloat(v) { return Number.isFinite(v); }

Try / catch

try { renderJson(value) } catch (e) { if (e.message.contains('cannotRenderValue')) renderJson(sanitizeFloats(value)) else throw e }

Prevention

When it happens

Trigger: Rendering output as JSON (JsonRenderer) where any reachable value is a Double equal to NaN, POSITIVE_INFINITY, or NEGATIVE_INFINITY — typically the result of 0.0/0.0, sqrt(-1) style math, or divide-by-zero on floats.

Common situations: Computing metrics or ratios in Pkl that divide by zero; importing data containing NaN from calculations; converting scientific/numeric configs where a sentinel infinity crept in.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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