apple/pkl · error

typeMismatch

Error message

typeMismatch

What it means

Pkl's internal `ApplyVmFunction2Node.executeBoolean` calls a two-argument Pkl function and requires the result to be a Boolean. If the result is not a Boolean, a `typeMismatch` error is thrown against `base::Boolean`. This is used by call sites (e.g. binary-operator-style function application) that assume a Boolean return.

Solutions

  1. Make the two-argument function a proper predicate: its body must evaluate to a Boolean comparison (e.g. `a <= b`).
  2. Cover all branches so the function never evaluates to null.
  3. If you meant to provide a key/transform function, pass it to the parameter that expects that role rather than the comparator role.
  4. Assert the final expression with a comparison to catch accidental non-Boolean results.

Example fix

// before (pkl)
sorted(items, (a, b) -> a.length - b.length)   // Int result -> typeMismatch (expected Boolean)

// after
sorted(items, (a, b) -> a.length <= b.length)
Defensive patterns

Strategy: type-guard

Validate before calling

// pkl
assert(comparatorResult is Boolean, "comparator must return a Boolean")

Type guard

function isBool2(f: (Any, Any) -> Any, a: Any, b: Any): Boolean = f(a, b) is Boolean

Prevention

When it happens

Trigger: A two-argument function (typically a comparator or binary predicate, e.g. passed to sort/compare operators) is invoked via executeBoolean and returns a non-Boolean value such as Int, String, or null.

Common situations: A comparator lambda returns the compared values or a difference instead of a Boolean test; a predicate omits a branch so it evaluates to null; using a key-extraction function where a comparator was expected.

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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/lambda/ApplyVmFunction2Node.java:35

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import org.pkl.core.ast.PklNode;
import org.pkl.core.runtime.*;

public abstract class ApplyVmFunction2Node extends PklNode {
  public abstract Object execute(VmFunction function, Object arg1, Object arg2);

  public final boolean executeBoolean(VmFunction function, Object arg1, Object arg2) {
    var result = execute(function, arg1, arg2);
    if (result instanceof Boolean b) return b;

    CompilerDirectives.transferToInterpreter();
    throw exceptionBuilder().typeMismatch(result, BaseModule.getBooleanClass()).build();
  }

  public final VmCollection executeCollection(VmFunction function, Object arg1, Object arg2) {
    var result = execute(function, arg1, arg2);
    if (result instanceof VmCollection collection) return collection;

    CompilerDirectives.transferToInterpreter();
    throw exceptionBuilder().typeMismatch(result, BaseModule.getCollectionClass()).build();
  }

  public final VmMap executeMap(VmFunction function, Object arg1, Object arg2) {
    var result = execute(function, arg1, arg2);
    if (result instanceof VmMap map) return map;

    CompilerDirectives.transferToInterpreter();
    throw exceptionBuilder().typeMismatch(result, BaseModule.getMapClass()).build();
  }

View on GitHub (pinned to f3efcbfc9b)