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
- Call it on the module itself: `module.relativePathTo(other)` or the module's implicit receiver
- Ensure the receiver is imported with `import "..."` so it is a module object
- Use `(import("..."))::relativePathTo(other)` style access if calling from another module
- 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
- Call relativePathTo on the module binding, not nested objects
- Avoid shadowing `module` inside class/object scopes
- Ensure receivers come from import statements
- Prefer `module.relativePathTo(...)` explicitly for clarity
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
- expectedModuleAsArgument
- noDescendentPathBetweenModules
- cannotFindStdLibModule
- externalClass
- cannotInstantiateExternalClass
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/1c38b96e88f96bf3.
Report an issue: GitHub.