apple/pkl · error
invalid for-generator modifier (dynamic errorMessageKey)
Error message
invalid for-generator modifier (dynamic errorMessageKey)
What it means
Pkl's AST builder rejects modifiers such as `...` (spread), `*` (defaults), or `when`/`is` predicates in a `for` generator position where they are not allowed. The builder walks up the parse tree to the enclosing ForGenerator node and attaches the error to the generator's source span. It means the object-spread/amend syntax you wrote cannot be combined with a for-generator in that position.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:3185
private @Nullable Pair<@Nullable FrameDescriptorBuilder, FrameSlotVariable[]>
createFrameDescriptorBuilderAndSlotVariables(ObjectBody body) {
if (body.getParameters().isEmpty()) return null;
var builder = new FrameDescriptorBuilder(body.getParameters().size());
return Pair.of(builder, getSlotVariables(body.getParameters(), builder));
}
private void checkNotInsideForGenerator(Node ctx, String errorMessageKey) {
if (!symbolTable.getCurrentScope().isForGeneratorScope()) {
return;
}
var forExprCtx = ctx.parent();
while (forExprCtx != null
&& forExprCtx.getClass() != org.pkl.parser.syntax.ObjectMember.ForGenerator.class) {
forExprCtx = forExprCtx.parent();
}
assert forExprCtx != null;
throw exceptionBuilder()
.evalError(errorMessageKey)
.withSourceSection(
createSourceSection(
((org.pkl.parser.syntax.ObjectMember.ForGenerator) forExprCtx).forSpan()))
.build();
}
private void checkDuplicateMember(
org.pkl.core.runtime.Identifier memberName,
SourceSection headerSection,
// use Set<String> rather than Set<Identifier>
// to detect conflicts between local and non-local identifiers
Set<String> visited) {
if (!visited.add(memberName.toString())) {
throw exceptionBuilder()
.evalError("duplicateDefinition", memberName)
.withSourceSection(headerSection)View on GitHub (pinned to f3efcbfc9b)
Solutions
- Move the spread/default/conditional modifier out of the for-generator body onto a plain object member or the enclosing object
- Iterate and emit plain properties inside the for body instead of using the invalid modifier
- Check the Pkl language spec for which modifiers are legal on for-generator members
Example fix
// before
foo {
for (item in items) {
...item.props // invalid modifier in for generator
}
}
// after
foo {
...items.first.props
for (item in items.drop(1)) {
["item-\(item.name)"] { ...item.props }
}
} Defensive patterns
Strategy: validation
Validate before calling
// before relying on modifiers inside a for generator, keep the body to plain members:
function usesOnlyPlainMembers(body: Listing<*>) = body.isEmpty() // review manually: for(...) { ... } must not contain `...`/amend modifiers Prevention
- Keep for-generator bodies limited to plain property/entry members
- Apply spread/default modifiers on the enclosing object, not inside for generators
- Lint Pkl sources for `...` inside for blocks
When it happens
Trigger: Writing an object member whose modifier is invalid inside a `for (...) { ... }` generator in a Pkl module, e.g. spreading `...expr` or using an amend modifier on a for-generated member where the grammar disallows it.
Common situations: Copy-pasting object-spread patterns into for-generator bodies; assuming `for` generators support the same spread/defaults modifiers as plain object bodies; refactoring amends into generated members.
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
- missingDelimiter
- unexpectedEndOfFile
- stringContentMustBeginOnNewLine
- notAUnion
- closingStringDelimiterMustBeginOnNewLine
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/d11ad3fb0c3c71f3.
Report an issue: GitHub.