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
- Convert the value to `Dynamic` or a typed object, e.g. `new Dynamic { ... }` or `new { ... }`
- If it is a Mapping/Listing, wrap or convert it (`toDynamic()` style) before rendering
- 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
- Ensure output.value is a typed object or Dynamic when using PcfRenderer
- Avoid Mapping/Listing as top-level Pcf values
- Validate output value shape in CI by rendering all modules
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
- invalidPListTopLevelValue
- invalidPropertiesTopLevelValue
- invalidProtobufTopLevelValue
- Values of type `Duration` cannot be rendered as JSON. Value:
- Values of type `DataSize` cannot be rendered as JSON. Value:
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/22422e4e78b06600.
Report an issue: GitHub.