apple/pkl · error · VmException

invalidPcfTopLevelValue

invalidPcfTopLevelValue

Error message

invalidPcfTopLevelValue

What it means

The Pcf renderer requires the top-level value to be a typed object (`VmTyped`) or `Dynamic`. Rendering any other value (Mapping, List, Map, scalar) as a Pcf document is invalid, so the error names the actual class encountered.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/PcfRenderer.java:152

    builder.append(VmUtils.readTextProperty(value));
  }

  private void visitPcfRenderDirective(VmTyped value) {
    var before = VmUtils.readMember(value, Identifier.BEFORE);
    if (before instanceof String string) { // not VmNull
      builder.append(string);
    }
    visit(VmUtils.readMember(value, Identifier.VALUE));
    var after = VmUtils.readMember(value, Identifier.AFTER);
    if (after instanceof String string) { // not VmNull
      builder.append(string);
    }
  }

  @Override
  protected void visitDocument(Object value) {
    if (!(value instanceof VmTyped || value instanceof VmDynamic)) {
      throw new VmExceptionBuilder()
          .evalError("invalidPcfTopLevelValue", VmUtils.getClass(value))
          .withProgramValue("Value", value)
          .build();
    }
    isDocument = true;
    topLevelValue = value;
    visit(value);
    if (!builder.isEmpty()) {
      builder.append('\n');
    }
  }

  @Override
  protected void visitTopLevelValue(Object value) {
    topLevelValue = value;
    visit(value);
  }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Convert the value to `Dynamic` or a typed object, e.g. `new Dynamic { ... }` or `new { ... }`
  2. If it is a Mapping/Listing, wrap or convert it (`toDynamic()` style) before rendering
  3. Choose a renderer that accepts the value's shape (e.g. JSON/YAML renderer for maps and lists)

Example fix

// before
output.value = new Mapping { ["a"] = 1 }
output.renderer = new PcfRenderer
// after
output.value = new Dynamic { a = 1 }
output.renderer = new PcfRenderer
Defensive patterns

Strategy: validation

Validate before calling

function isPcfTopLevel(v) { return isPklTyped(v) || isPklDynamic(v); }

Type guard

const isPcfRenderable = (v) => isPklTyped(v) || isPklDynamic(v);

Try / catch

try { renderAsPcf(value) } catch (e) { if (e.code === 'invalidPcfTopLevelValue') { /* convert to Dynamic */ } else throw e }

Prevention

When it happens

Trigger: Setting `output.renderer = new PcfRenderer` (or `output.text = value.renderAsPcf()`) where the value is a Mapping, Listing, Map, List, or primitive rather than a typed object or Dynamic.

Common situations: Rendering a `Mapping` or `Listing` to Pcf; accidentally assigning `output.value` to a collection when Pcf output expects an object-like value.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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