apple/pkl · error

notAModuleType

notAModuleType

Error message

notAModuleType

What it means

Raised by `UnresolvedTypeNode.Module#execute`: a type annotation references a module (an object known to be a module), but that module object is not a prototype, so it cannot be used as a type. The error message `notAModuleType` includes the module name. Pkl requires type positions to reference module prototypes (the module itself), not instances/amendments of it.

Solutions

  1. Use the plain module import in type position: `import "myModule.pkl"` then `x: myModule`.
  2. Do not amend or instantiate the module object that you reference as a type; keep a separate import for type use.
  3. If dynamic `import()` is needed, ensure the resolved value is the untouched module prototype.
  4. Check the module name in the error message and verify the referenced identifier is the module itself.

Example fix

// before
import "config.pkl"
mod = (config) { x = 1 }
y: mod = ...   // mod is amended, not a prototype
// after
import "config.pkl"
y: config = ...
Defensive patterns

Strategy: type-guard

Validate before calling

function expectModulePrototype(mod) {
  if (!mod || mod.__amended) throw new Error("type annotations must reference the module prototype, not an amendment");
}

Type guard

function isModulePrototype(v) { return v != null && typeof v === "object" && v.__isModule === true && !v.__amended; }

Try / catch

try {
  useAsType(mod);
} catch (e) {
  // re-import the module prototype and retry
}

Prevention

When it happens

Trigger: Writing a type annotation that resolves to a non-prototype module object, e.g. `x: someModule` where `someModule` was obtained by amending or instantiating rather than importing, or using `import()` result stored in a variable that got amended.

Common situations: Amending a module in a variable and then using the variable in type position; `import("...")` assigned and mutated before use as a type; typos that resolve to a submodule instance instead of the module class.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/UnresolvedTypeNode.java:218

            case "UInt16":
              return new UIntTypeAliasTypeNode(alias, 0x000000000000FFFFL);
            case "Int32":
              return new Int32TypeAliasTypeNode();
            case "UInt32":
              return new UIntTypeAliasTypeNode(alias, 0x00000000FFFFFFFFL);
            case "UInt":
              return new UIntTypeAliasTypeNode(alias, 0x7FFFFFFFFFFFFFFFL);
          }
        }

        return new TypeAliasTypeNode(sourceSection, alias, new TypeNode[0]);
      }

      var module = (VmTyped) type;
      assert module.isModuleObject();
      var clazz = module.getVmClass();
      if (!module.isPrototype()) {
        throw exceptionBuilder().evalError("notAModuleType", clazz.getModuleName()).build();
      }
      return TypeNode.forClass(sourceSection, module.getVmClass());
    }
  }

  public static final class Parameterized extends UnresolvedTypeNode {
    private final VmLanguage language;
    @Child private ExpressionNode resolveTypeNode;
    @Children private final UnresolvedTypeNode[] typeArgumentNodes;

    public Parameterized(
        SourceSection sourceSection,
        VmLanguage language,
        ExpressionNode resolveTypeNode,
        UnresolvedTypeNode[] typeArgumentNodes) {
      super(sourceSection);
      this.language = language;
      this.resolveTypeNode = resolveTypeNode;

View on GitHub (pinned to f3efcbfc9b)