apple/pkl · error · VmException
moduleIsNotConstAnnotation
moduleIsNotConstAnnotation
Error message
moduleIsNotConstAnnotation
What it means
In Pkl, `module` can only be referenced as a value inside a const annotation or within class bodies where the module object itself is a compile-time constant. When a `module` expression is evaluated in a scope where it would not be constant (e.g. a plain property or method body), the AST builder rejects it. The message key distinguishes annotation scopes (moduleIsNotConstAnnotation) from class scopes (moduleIsNotConstClass).
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:653
public ExpressionNode visitModuleExpr(ModuleExpr expr) {
var currentScope = symbolTable.getCurrentScope();
// cannot use unqualified `module` in a const context
if (currentScope.getConstLevel().isConst() && !(expr.parent() instanceof QualifiedAccessExpr)) {
var scope = currentScope;
while (scope != null
&& !(scope instanceof AnnotationScope)
&& !(scope instanceof ClassScope)) {
scope = scope.getParent();
}
if (scope == null) {
throw exceptionBuilder()
.evalError("moduleIsNotConst", currentScope.getName().toString())
.withSourceSection(createSourceSection(expr))
.build();
}
var messageKey =
scope instanceof AnnotationScope ? "moduleIsNotConstAnnotation" : "moduleIsNotConstClass";
throw exceptionBuilder()
.evalError(messageKey)
.withSourceSection(createSourceSection(expr))
.build();
}
return symbolTable.isInTypeAliasScope
? new GetTypeAliasModuleNode(createSourceSection(expr))
: new GetModuleNode(createSourceSection(expr));
}
@Override
public ConstantValueNode visitNullLiteralExpr(NullLiteralExpr expr) {
return new ConstantValueNode(createSourceSection(expr), VmNull.withoutDefault());
}
@Override
public ExpressionNode visitBoolLiteralExpr(BoolLiteralExpr expr) {
if (expr.isB()) {
return new TrueLiteralNode(createSourceSection(expr));View on GitHub (pinned to f3efcbfc9b)
Solutions
- Remove the `module` expression from the annotation; annotations must be const-evaluable literals or simple type references.
- Move the module-relative value out of the annotation into a normal property or the annotated member itself.
- Use a fully qualified type or literal string in the annotation instead of module introspection.
Example fix
// before
@Deprecated { since = module.name }
prop x
// after
@Deprecated { since = "my/pkg" }
prop x Defensive patterns
Strategy: validation
Validate before calling
// Before relying on module introspection in an annotation, ensure the value is a literal:
const ann = new Annotation {
since: "my/pkg" // literal, not `module.name`
} Prevention
- Never reference `module` inside annotations; annotations must be const-evaluable.
- Keep module-relative strings as plain literals in annotation parameters.
When it happens
Trigger: Writing `module` inside an annotation when the enclosing scope's const level permits non-const evaluation, i.e. `visitModuleExpr` detects the current scope is an AnnotationScope but the const check already failed.
Common situations: Using `module.name` or `module.dir` inside a custom annotation definition, attempting to parameterize annotations with module-relative values.
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
- expectedAnnotationClass
- Node `%s` of type `%s` does not have a property named `%s`.
- JavaType token must be parameterized.
- Leaf node `%s` of type `%s` does not have a child named `%s`
- Node `%s` of type `%s` does not have a key named `%s`. Avail
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/b97588fd6521d224.
Report an issue: GitHub.