apple/pkl · error · VmTypeMismatchException

type mismatch: value is not of type Reference

Error message

type mismatch: value is not of type Reference

What it means

Thrown by the @Fallback path of the Reference class type check (Ref module). The value failed an `is Reference` check used by `Ref`-typed annotations (e.g. typed object references like `Ref<Map>` or `Ref<Listing>`).

Solutions

  1. Supply a Reference value (e.g. from `Ref` combinators or a reference-typed property) rather than a raw value.
  2. If you have the underlying value, wrap or reference it per the Ref module API instead of passing it directly.
  3. Remove an unintended `Ref<T>` annotation if a plain `T` was intended.
  4. Check that null is not sneaking into a Ref-typed slot.

Example fix

// before
r: Ref<Mapping> = new Mapping {}

// after
r: Ref<Mapping> = someRef // a value of type Ref<Mapping>
Defensive patterns

Strategy: type-guard

Validate before calling

if (value is Reference) { /* ok */ } else { /* wrap or fix */ }

Type guard

function isReference(v: Any): Boolean = v is Reference

Prevention

When it happens

Trigger: A value is checked against a `Ref<...>` type annotation but the value is not a Reference — e.g. an Int, String, null, or a plain object where `Ref<T>` requires a reference to a T.

Common situations: Using Ref-module APIs or `Ref<T>` annotations and passing the contained value directly instead of a reference; passing a concrete value (like a string) where a reference to a typed object 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/ec748ed862bb131b. Report an issue: GitHub.

Appendix: source

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

      var moduleClass = VmUtils.getClass(getModuleNode.executeGeneric(frame));

      return doEval(value, thisClass, moduleClass);
    }

    @TruffleBoundary
    private Object doEval(VmReference value, VmClass thisClass, VmClass moduleClass) {
      var referentType = referentTypeNode.doExport();
      if (value.referentTypeIsSubtypeOf(referentType, thisClass.export(), moduleClass.export())) {
        return value;
      }

      throw new VmTypeMismatchException.Reference(
          sourceSection, value, domainTypeNode.doExport(), referentType);
    }

    @Fallback
    protected Object fallback(Object value) {
      throw typeMismatch(value, RefModule.getReferenceClass());
    }

    @Override
    protected boolean acceptTypeNode(boolean visitTypeArguments, TypeNodeConsumer consumer) {
      if (visitTypeArguments)
        return consumer.accept(this)
            && consumer.accept(domainTypeNode)
            && consumer.accept(referentTypeNode);
      return consumer.accept(this);
    }

    @Override
    public VmClass getVmClass() {
      return RefModule.getReferenceClass();
    }

    @Override
    public VmList getTypeArgumentMirrors() {

View on GitHub (pinned to f3efcbfc9b)