apple/pkl · error · VmTypeMismatchException

type mismatch: type constraint must be a Boolean or a Functi

Error message

type mismatch: type constraint must be a Boolean or a Function

What it means

Pkl type constraints (`x is T || cond`) must evaluate to a Boolean or be a Function taking the constrained value. TypeConstraintNode.fallback throws a type mismatch when the constraint expression is neither — this is always fatal, even inside union types.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/TypeConstraintNode.java:122

          throw new VmTypeMismatchException.Constraint(
              sourceSection,
              value,
              function.getRootNode().getSourceSection(),
              valueTracker.values());
        }
      } else {
        throw new VmTypeMismatchException.Constraint(
            sourceSection, value, function.getRootNode().getSourceSection(), null);
      }
    }
  }

  @Fallback
  protected void fallback(Object object) {
    // supplying a type constraint that's neither a boolean nor a function
    // is always fatal (even within a union type), hence throw VmEvalException
    CompilerDirectives.transferToInterpreter();
    throw exceptionBuilder()
        .typeMismatch(object, BaseModule.getBooleanClass(), BaseModule.getFunctionClass())
        .build();
  }

  protected static ApplyVmFunction1Node createApplyNode() {
    return ApplyVmFunction1Node.create();
  }

  private void initConstraintSlot(VirtualFrame frame) {
    if (customThisSlot == -1) {
      CompilerDirectives.transferToInterpreterAndInvalidate();
      // deferred until execution time s.t. nodes of inlined type aliases get the right frame slot
      customThisSlot = VmUtils.findCustomThisSlot(frame);
    }
  }
}

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Make the constraint evaluate to a Boolean (e.g. `x > 0`)
  2. If using a function constraint, ensure it is a `Function1` returning Boolean
  3. Fix expressions that return the value or a non-Boolean result

Example fix

// before
x: Int(this)  // constraint yields the value, not a Boolean
// after
x: Int(isPositive) where { isPositive = this > 0 }
Defensive patterns

Strategy: validation

Validate before calling

// constraints must yield Boolean
if (typeof constraint === "function") { /* ok */ } else if (typeof constraint !== "boolean") throw new Error("constraint must be Boolean or Function");

Type guard

function isBooleanOrFn(x){ return typeof x === "boolean" || typeof x === "function"; }

Try / catch

try { evaluateConstraint(x); } catch (e) { if (String(e).includes("type constraint")) throw new Error("fix constraint to return Boolean"); throw e; }

Prevention

When it happens

Trigger: Declaring a type constraint whose body evaluates to a non-Boolean, non-Function value, e.g. `x -> 42`, a constraint returning a String/Number, or referencing a property instead of a predicate.

Common situations: Writing a constraint that returns the value itself instead of a comparison; forgetting the comparison in a lambda; supplying an object where a predicate is 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/5184a267c0650ed9. Report an issue: GitHub.