apple/pkl · error · VmTypeMismatchException

type mismatch: value is not of type Collection

Error message

type mismatch: value is not of type Collection

What it means

Pkl `Collection` type check failure. The `Collection` type accepts VmList and VmSet (which are then element-wise checked/conformed via evalList/evalSet); any other value (String, Int, Dynamic, Typed object, Mapping, null) fails with `typeMismatch(value, BaseModule.getCollectionClass())`.

Source

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

  }

  public static final class CollectionTypeNode extends ObjectSlotTypeNode {
    @Child private TypeNode elementTypeNode;

    public CollectionTypeNode(SourceSection sourceSection, TypeNode elementTypeNode) {
      super(sourceSection);
      this.elementTypeNode = elementTypeNode;
    }

    @Override
    protected Object executeLazily(VirtualFrame frame, Object value) {
      if (value instanceof VmList vmList) {
        return evalList(frame, vmList);
      }
      if (value instanceof VmSet vmSet) {
        return evalSet(frame, vmSet);
      }
      throw typeMismatch(value, BaseModule.getCollectionClass());
    }

    @Override
    public Object executeEagerly(VirtualFrame frame, Object value) {
      if (value instanceof VmList vmList) {
        return evalListEagerly(frame, vmList);
      }
      if (value instanceof VmSet vmSet) {
        // sets are always checked eagerly
        return evalSet(frame, vmSet);
      }
      throw typeMismatch(value, BaseModule.getCollectionClass());
    }

    @Override
    public Object createDefaultValue(
        VirtualFrame frame,
        VmLanguage language,

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Wrap the value in a list: `List(item)` or `new Listing { item }`.
  2. If it is a Mapping, change the declared type to `Mapping` instead of `Collection`.
  3. If any sequence kind works, declare `List` or `Set` explicitly to match what you produce.
  4. Ensure default values are `List()` rather than null for collection-typed properties.

Example fix

// before
tags: Collection = "red"
// after
tags: Collection = List("red")
Defensive patterns

Strategy: type-guard

Validate before calling

// Pkl
if (value is List || value is Set) {
  coll: Collection = value
} else {
  coll: Collection = List(value)
}

Type guard

function isCollection(value: Any): Boolean = value is List || value is Set

Try / catch

// Guard with `is List || is Set` and wrap singles in List(...); embedders: catch PklException with 'not of type Collection'.

Prevention

When it happens

Trigger: Assigning a non-list/non-set value to a property or parameter typed `Collection`; passing a Mapping or a single element where a Collection is required; null where the collection type has no default.

Common situations: Confusing `Mapping` (keyed) with `Collection` (sequence), forgetting to wrap a single item in a list (`List(...)`), converting from JSON where an object vs array distinction differs.

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/75d06918a58e8eab. Report an issue: GitHub.