apple/pkl · error · VmTypeMismatchException

type mismatch: value is not of type List

Error message

type mismatch: value is not of type List

What it means

Thrown by the List type-check node's executeEagerly when a value checked against a `List<T>` constraint is not a VmList. The type node first verifies the outer value is a List before running the per-element type check, so any non-List value (String, Set, Map, null, etc.) immediately fails. This is the eager (value fully evaluated) code path of List type checking.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java:1371

    public TypeNode getElementTypeNode() {
      return elementTypeNode;
    }

    @Override
    public VmList getTypeArgumentMirrors() {
      return VmList.of(elementTypeNode.getMirror());
    }

    @Override
    protected PType doExport() {
      return new PType.Class(BaseModule.getListClass().export(), elementTypeNode.doExport());
    }

    @Override
    public Object executeEagerly(VirtualFrame frame, Object value) {
      if (!(value instanceof VmList vmList)) {
        throw typeMismatch(value, BaseModule.getListClass());
      }
      if (elementTypeNode.isNoopTypeCheck()) return vmList;

      for (var elem : vmList) {
        elementTypeNode.executeEagerly(frame, elem);
      }

      LoopNode.reportLoopCount(this, vmList.getLength());
      return value;
    }

    @SuppressWarnings("DuplicatedCode")
    @Override
    @ExplodeLoop
    protected Object executeLazily(VirtualFrame frame, Object value) {
      if (!(value instanceof VmList vmList)) {
        throw typeMismatch(value, BaseModule.getListClass());
      }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Wrap or convert the value into a List: `List(...)` or `.toList()` where available.
  2. If the value is a Set/Listing, change the declared type to the matching collection type.
  3. Check each element too: once the outer type passes, elements must satisfy `T`.
  4. Reproduce in the REPL with `"...": List<Int>` style assertion to see which value fails.

Example fix

// before
ports: List<Int> = Set(8080, 9090)
// after
ports: List<Int> = List(8080, 9090)
Defensive patterns

Strategy: type-guard

Validate before calling

assert(xs is List, "expected a List, got ${xs.getClass().simpleName}")

Type guard

xs: List<Int> = if (xs is List) xs else throw("not a List") // or host: value is PklList

Prevention

When it happens

Trigger: Evaluating a property/typealias/assert declared `List<T>` where the bound value is not a Pkl List instance, e.g. `xs: List<Int> = Set(1,2)` or `xs: List<Int> = 5`.

Common situations: Confusing List with Set or Listing; passing a string where a list of strings was intended; returning a Map from an expression typed as List; misconfigured external property (e.g. CLI/env-provided value substituted as scalar).

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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