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
- Pass an imported module object: `module.relativePathTo(import("other.pkl"))`
- Import the target file first and pass the module binding, not a string path
- Verify the argument is produced by an import statement, not a property lookup
- 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
- Import the target module and pass the module binding, never a path string
- Never pass Dynamic/plain objects to module-to-module APIs
- Check the argument is the result of `import "..."`
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
- expectedModuleAsReceiver
- noDescendentPathBetweenModules
- FormatException("string", obj.getClass())
- cannotFindStdLibModule
- externalClass
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/0b8fb4e992b15e84.
Report an issue: GitHub.