apple/pkl · error

expectedModuleAsArgument

expectedModuleAsArgument

Error message

expectedModuleAsArgument

What it means

Thrown by Module.relativePathTo when the argument (the other object) is not a module object. The receiver was already verified to be a module, but relativizing a path requires both sides to have module keys/URIs, so a non-module argument is rejected with this error.

Source

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

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);
        }
      }

      throw exceptionBuilder()
          .evalError("noDescendentPathBetweenModules", selfUri, otherUri)

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Pass an imported module object: `module.relativePathTo(import("other.pkl"))`
  2. Import the target file first and pass the module binding, not a string path
  3. Verify the argument is produced by an import statement, not a property lookup
  4. If you only have a path, import it dynamically or compute the relative path with string/URI utilities instead

Example fix

// before
module.relativePathTo("../lib/other.pkl") // string, not a module
// after
import "../lib/other.pkl"
module.relativePathTo(other)
Defensive patterns

Strategy: validation

Validate before calling

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

Prevention

When it happens

Trigger: Calling module.relativePathTo(x) where x is a plain object, Dynamic, class, or collection rather than an imported module object.

Common situations: Passing a nested object or property value instead of the module import, passing a file path string instead of the module, or mixing up argument order with another API that takes paths.

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