apple/pkl · error

expectedModuleAsReceiver

expectedModuleAsReceiver

Error message

expectedModuleAsReceiver

What it means

Thrown by Module.relativePathTo when the receiver (the object the method is called on) is not a module object. Both endpoints must be modules because the method computes a URI-relative path between module keys; a non-module object has no module key/URI to relativize against.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/ModuleClassNodes.java:36

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import java.net.URI;
import org.pkl.core.runtime.*;
import org.pkl.core.stdlib.ExternalMethod1Node;
import org.pkl.core.stdlib.PklName;

@PklName("Module")
public final class ModuleClassNodes {
  private ModuleClassNodes() {}

  public abstract static class relativePathTo extends ExternalMethod1Node {
    @Specialization
    @TruffleBoundary
    protected VmList eval(VmObjectLike self, VmObjectLike other) {
      if (!self.isModuleObject()) {
        CompilerDirectives.transferToInterpreter();
        throw exceptionBuilder().evalError("expectedModuleAsReceiver").build();
      }
      if (!other.isModuleObject()) {
        CompilerDirectives.transferToInterpreter();
        throw exceptionBuilder().evalError("expectedModuleAsArgument").build();
      }
      var selfKey = VmUtils.getModuleInfo(self).getModuleKey();
      var selfUri = selfKey.getUri();
      var otherKey = VmUtils.getModuleInfo(other).getModuleKey();
      var otherUri = otherKey.getUri();

      var index = selfUri.toString().lastIndexOf('/');
      if (index != -1) {
        var baseUri = URI.create(selfUri.toString().substring(0, index + 1));
        var relativizedUri = baseUri.relativize(otherUri);
        if (!relativizedUri.isAbsolute()) {
          var pathElements = relativizedUri.getPath().split("/");
          return VmList.create(pathElements, pathElements.length - 1);
        }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Call it on the module itself: `module.relativePathTo(other)` or the module's implicit receiver
  2. Ensure the receiver is imported with `import "..."` so it is a module object
  3. Use `(import("..."))::relativePathTo(other)` style access if calling from another module
  4. Verify you're not in a nested object scope where `this` refers to an inner object

Example fix

// before
myObject.relativePathTo(otherModule)
// after
module.relativePathTo(otherModule)
Defensive patterns

Strategy: validation

Validate before calling

function isModuleReceiver(obj: Any): Boolean = obj is Module

Prevention

When it happens

Trigger: Calling relativePathTo on a plain object, Dynamic, List, or any non-module value: e.g. `someObject.relativePathTo(otherModule)` instead of `module.relativePathTo(otherModule)`.

Common situations: Calling the method inside a class or nested object where `this` is not the module, accidentally shadowing `module`, or importing the method conceptually as a free function and applying it to the wrong receiver.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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