apple/pkl · error
cannotDefineExternalMember
cannotDefineExternalMember
Error message
cannotDefineExternalMember
What it means
Pkl throws `cannotDefineExternalMember` when a member is declared `external` in a module that is not a standard library module. `external` members are reserved for the built-in `pkl.*` stdlib whose implementations live in native runtime code; user modules cannot provide external members (AstBuilder.java:3009).
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:3009
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()
.evalError("redundantHiddenModifier")
.withSourceSection(createSourceSection(modifiers, ModifierValue.HIDDEN))
.build();
}
if (VmModifier.isLocal(result) && VmModifier.isFixed(result)) {
throw exceptionBuilder()
.evalError("redundantFixedModifier")
.withSourceSection(createSourceSection(modifiers, ModifierValue.FIXED))
.build();
}View on GitHub (pinned to f3efcbfc9b)
Solutions
- Remove the `external` modifier and provide a concrete implementation.
- If declaring an interface-like contract, use `abstract` in a class instead.
- If extending stdlib behavior, define a normal function/property rather than an external member.
Example fix
// before external function hash(input: String): String // after function hash(input: String): String = "todo"
Defensive patterns
Strategy: validation
Validate before calling
if (/^\s*external\b/m.test(pklSource) && !isStdLibModule(moduleName)) {
throw new Error("external members are reserved for pkl.* standard library modules");
} Prevention
- Never declare `external` in application modules — it is stdlib-only.
- Use `abstract` (in classes) or a `throw`-ing default body for stubs.
- When reading stdlib source, don't copy `external` declarations into user code.
When it happens
Trigger: Declaring `external foo: String` or `external function f()` in a user-defined module whose key is not in ModuleKeys stdlib set.
Common situations: Mimicking stdlib declarations when writing custom modules; copying declarations out of pkl-base source into user code; trying to stub native functions.
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
- cannotFindStdLibModule
- cannotInstantiateExternalClass
- expectedNonEmptyListing
- expectedSingleElementListing
- Cannot parse `%s` as number.
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/029779ac945317df.
Report an issue: GitHub.