apple/pkl · error
invalidObjectMemberModifier
invalidObjectMemberModifier
Error message
invalidObjectMemberModifier (dynamic errorMessage key)
What it means
`doVisitModifiers` validates each modifier against a bitmask of modifiers valid in the current context; when a modifier (e.g. `abstract` on a property, or `hidden` on a class) is not allowed, it throws `invalidObjectMemberModifier` with the modifier name interpolated into the message (AstBuilder.java:2998).
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:2998
var previousValue = EconomicMaps.put(members, key, value);
if (previousValue != null) {
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder()
.evalError("duplicateDefinition", new ProgramValue("", key))
.withSourceSection(value.getHeaderSection())
.build();
}
}
}
private int doVisitModifiers(
List<? extends Modifier> modifiers, int validModifiers, String errorMessage) {
var result = VmModifier.NONE;
for (var ctx : modifiers) {
int modifier = visitModifier(ctx);
if ((modifier & validModifiers) == 0) {
throw exceptionBuilder()
.evalError(errorMessage, ctx.getValue().name().toLowerCase(Locale.ROOT))
.withSourceSection(createSourceSection(ctx))
.build();
}
result += modifier;
}
// flag modifier combinations that are never valid right away
if (VmModifier.isExternal(result) && !ModuleKeys.isStdLibModule(moduleKey)) {
throw exceptionBuilder()
.evalError("cannotDefineExternalMember")
.withSourceSection(createSourceSection(modifiers, ModifierValue.EXTERNAL))
.build();
}
if (VmModifier.isLocal(result) && VmModifier.isHidden(result)) {
throw exceptionBuilder()View on GitHub (pinned to f3efcbfc9b)
Solutions
- Read the interpolated modifier name in the message and remove it from that declaration.
- Check Pkl docs for modifiers valid for the member kind (properties: `local`, `hidden`, `fixed`, `external`; classes: `open`, `abstract`, `open` etc.).
- Move the modifier to the correct declaration site if it belongs elsewhere.
Example fix
// before abstract foo = 1 // after foo = 1
Defensive patterns
Strategy: validation
Validate before calling
// valid member modifiers per Pkl grammar: local, hidden, fixed, external, abstract
const VALID = new Set(["local", "hidden", "fixed", "external", "abstract", "open"]);
const mods = [...pklSource.matchAll(/^\s*([a-zA-Z]+)\s+[a-zA-Z_]\w*/gm)].map(m => m[1]);
mods.forEach(m => { if (!VALID.has(m)) throw new Error(`invalid modifier: ${m}`); }); Prevention
- Check the Pkl language reference table of valid modifiers per declaration kind.
- Add one modifier at a time and re-run `pkl eval`.
- Don't copy modifier lists blindly between class and property declarations.
When it happens
Trigger: Using a modifier outside its allowed context, e.g. `open`/`abstract` on a non-class member, `fixed` on an object method, or any member modifier at module level where only a subset is valid.
Common situations: Copy-pasting modifiers between property/class declarations; misunderstanding which modifiers apply to object members vs classes; typos producing unexpected modifier placements.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- moduleMethodMustBeLocal
- redundantHiddenModifier
- redundantFixedModifier
- redundantOpenModifier
- expectedNonEmptyCollection
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/dfd1106895a7c58a.
Report an issue: GitHub.