apple/pkl · error · VmException
cannotFindModule
cannotFindModule
Error message
cannotFindModule
What it means
ModuleCache.resolve throws cannotFindModule when a module URI (typically a relative/path or unregistered scheme import) cannot be resolved or loaded by any registered module key factory; the module file does not exist at the resolved location or no factory can handle the URI. If the path contains backslashes, a hint about using `/` as directory separator is attached. IOExceptions during loading surface separately as ioErrorLoadingModule.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/runtime/ModuleCache.java:217
private ResolvedModuleKey resolve(
ModuleKey module, SecurityManager securityManager, @Nullable Node importNode) {
try {
return module.resolve(securityManager);
} catch (SecurityManagerException | PackageLoadError | HttpClientException e) {
throw new VmExceptionBuilder().withOptionalLocation(importNode).withCause(e).build();
} catch (FileNotFoundException | NoSuchFileException e) {
var exceptionBuilder =
new VmExceptionBuilder()
.withOptionalLocation(importNode)
.evalError("cannotFindModule", module.getUri());
var path = module.getUri().getPath();
if (path != null && path.contains("\\")) {
exceptionBuilder.withHint(
"To resolve modules in nested directories, use `/` as the directory separator.");
}
throw exceptionBuilder.build();
} catch (IOException e) {
throw new VmExceptionBuilder()
.withOptionalLocation(importNode)
.evalError("ioErrorLoadingModule", module.getUri())
.withCause(e)
.build();
}
}
}
View on GitHub (pinned to f3efcbfc9b)
Solutions
- Fix the import path (check spelling and that the file exists relative to the importing module).
- Replace backslashes with forward slashes if the path contains `\`.
- Register the appropriate ModuleKeyFactory/module path mapping if using a custom scheme or embedded resolver.
Example fix
// before import "configs\settings.pkl" // after import "configs/settings.pkl"
Defensive patterns
Strategy: validation
Validate before calling
fun assertImportable(importerPath: Path, importPath: String) {
require('\\' !in importPath) { "use '/' as directory separator" }
val resolved = importerPath.toAbsolutePath().parent!!.resolve(importPath).normalize()
require(java.nio.file.Files.exists(resolved)) { "module not found: $resolved" }
} Prevention
- Always use forward slashes in module imports
- Run evaluations from a stable working directory or use project-relative imports
- Verify referenced files exist in version control/CI
When it happens
Trigger: `import "relative/path/to.pkl"` where the file does not exist; importing a module via a scheme with no registered ModuleKeyFactory; Windows-style backslash paths pasted into imports.
Common situations: Wrong working directory when evaluating; missing files in a project layout; typos in module paths; moving modules without updating imports; running on Windows with `\` separators in import strings.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- cannotFindStdLibModule
- Failed to convert `pkl.base#String` to `java.nio.file.Path`.
- Is a directory
- missingPathInPackageUri
- invalidRelativeProjectImport
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/b4abf5251fc1d232.
Report an issue: GitHub.