apple/pkl · error · VmException

thisIsNotConst

thisIsNotConst

Error message

thisIsNotConst

What it means

AstBuilder.visitThisExpr throws 'thisIsNotConst' when unqualified `this` appears in a const context (e.g. inside an annotation argument), because const evaluation requires statically fixed values and `this` is not const there. The input at fault is a bare `this` expression used in an annotation/const position.

Solutions

  1. Qualify the access (e.g. `this.foo` on a named receiver) or restructure so no `this` is needed in the const context.
  2. Use a literal or constant value in the annotation instead.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:606 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/baa7b2bd186e3d01. Report an issue: GitHub.

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:606

    var pars = new UnresolvedTypeNode[type.getArgs().size()];
    for (int i = 0; i < pars.length; i++) {
      pars[i] = visitType(type.getArgs().get(i));
    }

    return new UnresolvedTypeNode.Function(
        createSourceSection(type), pars, visitType(type.getRet()));
  }

  @Override
  public ExpressionNode visitThisExpr(ThisExpr expr) {
    if (!(expr.parent() instanceof QualifiedAccessExpr)) {
      var currentScope = symbolTable.getCurrentScope();
      var needsConst =
          currentScope.getConstLevel() == ConstLevel.ALL
              && currentScope.getConstDepth() == -1
              && !currentScope.isCustomThisScope();
      if (needsConst) {
        throw exceptionBuilder()
            .withSourceSection(createSourceSection(expr))
            .evalError("thisIsNotConst")
            .build();
      }
    }
    return VmUtils.createThisNode(
        createSourceSection(expr), symbolTable.getCurrentScope().isCustomThisScope());
  }

  // TODO: `outer.` should probably have semantics similar to `super.`,
  // rather than just performing a lookup in the immediately enclosing object
  // also, consider interpreting `x = ... x ...` as `x = ... outer.x ...`
  @Override
  public OuterNode visitOuterExpr(OuterExpr expr) {
    if (!(expr.parent() instanceof QualifiedAccessExpr)) {
      var constLevel = symbolTable.getCurrentScope().getConstLevel();
      var outerScope = getParentLexicalScope();
      if (outerScope != null && constLevel.bigger(outerScope.getConstLevel())) {

View on GitHub (pinned to f3efcbfc9b)