apple/pkl · error

moduleCannotExtendSelf

moduleCannotExtendSelf

Error message

moduleCannotExtendSelf

What it means

Pkl throws moduleCannotExtendSelf when a module declares itself as its own superclass (e.g. `extends` naming the enclosing module). ClassNode.checkSupertype compares the resolved superclass with the cached class of the module being defined and rejects direct self-extension. A module extending itself would create a cyclic inheritance chain, so it is stopped at class-definition time.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/member/ClassNode.java:176

      cachedClass.onOwnClassInitialized();
      localContext.endClassInit();
      return cachedClass;
    } catch (Throwable e) {
      localContext.clearClassInitState();
      throw e;
    }
  }

  private void checkSupertype(TypeNode supertypeNode, @Nullable VmClass superclass) {
    if (superclass == null) {
      throw exceptionBuilder()
          .evalError("invalidSupertype", supertypeNode.getSourceSection().getCharacters())
          .withSourceSection(supertypeNode.getSourceSection())
          .build();
    }
    if (moduleInfo != null) {
      if (cachedClass == superclass) {
        throw exceptionBuilder()
            .evalError("moduleCannotExtendSelf", moduleInfo.getModuleName())
            .withSourceSection(supertypeNode.getSourceSection())
            .build();
      }
      if (superclass.isClosed()) {
        throw exceptionBuilder()
            .evalError("cannotExtendFinalModule", superclass.getModuleName())
            .withSourceSection(supertypeNode.getSourceSection())
            .build();
      }
    } else {
      if (cachedClass == superclass) {
        throw exceptionBuilder()
            .evalError("classCannotExtendSelf", superclass.getDisplayName())
            .withSourceSection(supertypeNode.getSourceSection())
            .build();
      }
      if (superclass.isClosed()) {

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Remove the `extends` clause that names the module itself.
  2. If you intended inheritance from a base config, extend a different module that does not (transitively) extend this one.
  3. Break any import cycle so the module does not reach itself through re-exports.
  4. Rename the target if you actually meant a different module with a similar name.

Example fix

// before (inside base.pkl)
module base
extends base  // module extends itself

// after
module base
Defensive patterns

Strategy: validation

Validate before calling

// Check the extends chain of a module before shipping:
// pkl eval base.pkl  -> moduleCannotExtendSelf surfaces at load
// Audit imports: a module must never import itself (directly or via a barrel module).

Prevention

When it happens

Trigger: Writing `extends <thisModuleName>` inside the module itself; a module importing itself (directly or via a re-export) and extending that import; circular module extends where the chain loops back to the same module.

Common situations: Copy-pasting an `extends` clause into the base module itself; refactoring a two-module hierarchy into one file and forgetting to drop the extends; accidentally importing a module into itself through a barrel/index module.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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