apple/pkl · error · RendererException
The top-level value of a YAML stream must have type `Collect
Error message
The top-level value of a YAML stream must have type `Collection`, but got type `%s`.
What it means
YamlRenderer.renderDocument, when rendering a YAML stream (isStream == true), requires the top-level value to be an Iterable so it can emit each element as a separate YAML document. Any other type throws RendererException stating the actual type name.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/YamlRenderer.java:92
@Override
public void write(String str, int off, int len) {
try {
writer.write(str, off, len);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
});
this.omitNullProperties = omitNullProperties;
this.isStream = isStream;
}
@Override
public void renderDocument(Object value) {
if (isStream) {
if (!(value instanceof Iterable<?> iterable)) {
throw new RendererException(
String.format(
"The top-level value of a YAML stream must have type `Collection`, but got type `%s`.",
value.getClass().getTypeName()));
}
emitter.emit(new StreamStartEvent());
for (var elem : iterable) {
emitter.emit(new DocumentStartEvent(false, Optional.empty(), Map.of()));
visitor.visit(elem);
emitter.emit(new DocumentEndEvent(false));
}
emitter.emit(new StreamEndEvent());
} else {
// a top-level YAML value can have any type
renderValue(value);
}
}
@OverrideView on GitHub (pinned to f3efcbfc9b)
Solutions
- Disable stream mode (renderer.setStream(false)) if you want a single YAML document.
- Wrap the value in a List before rendering when stream output is required.
- Change the Pkl module's output value to a List/Iterable so each element becomes its own document.
Example fix
// before renderer.setStream(true); renderer.renderDocument(mapping); // throws // after renderer.setStream(false); renderer.renderDocument(mapping);
Defensive patterns
Strategy: type-guard
Validate before calling
if (isStream && !(value instanceof Iterable)) {
throw new IllegalArgumentException("stream output requires a top-level list");
} Type guard
boolean isRenderableStreamRoot(Object v) { return v instanceof Iterable<?>; } Try / catch
try {
renderer.renderDocument(value);
} catch (RendererException e) {
if (e.getMessage().contains("YAML stream must have type `Collection`")) {
renderer.renderDocument(List.of(value)); // or disable stream mode
} else throw e;
} Prevention
- Match stream mode to the data shape: enable isStream only for list outputs.
- Normalize non-list roots by wrapping in List.of(...) before rendering.
- Assert the top-level output type in tests for each output format.
When it happens
Trigger: Creating a YamlRenderer with setStream(true) (or stream output mode) and calling renderDocument with a non-collection value such as a Mapping, List without Iterable at that level, String, or Number.
Common situations: Rendering a single Pkl object to YAML with stream mode accidentally enabled; CLI `pkl eval -f yaml` with a stream-flavored output when the module's output value is not a list.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Values of type `Duration` cannot be rendered as YAML. Value:
- Values of type `DataSize` cannot be rendered as YAML. Value:
- Maps with non-String keys cannot currently be rendered as YA
- Values of type `Class` cannot be rendered as YAML. Value: %s
- Error converting property `%s` in Pkl object of type `%s` to
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/c965bb56ae92e295.
Report an issue: GitHub.