apple/pkl · error · VmException
ioErrorLoadingModule
ioErrorLoadingModule
Error message
ioErrorLoadingModule
What it means
ioErrorLoadingModule is an evaluation error thrown when the Pkl evaluator fails to read a module's source over I/O during module source normalization (EvaluatorImpl.normalizeModuleSource). The module URI is included in the error so the developer knows which resource could not be loaded. It wraps an IOException encountered while resolving/reading the module (e.g. from a file, HTTP, or package-backed module source).
Source
Thrown at pkl-core/src/main/java/org/pkl/core/EvaluatorImpl.java:457
private ModuleSource normalizeModuleSource(ModuleSource moduleSource) {
if (moduleSource.getContents() != null
|| moduleSource.getUri().isAbsolute()
|| !moduleSource.getUri().getPath().startsWith("@")) {
return moduleSource;
}
try {
if (projectFileUri != null) {
var moduleKey = moduleResolver.resolve(projectFileUri);
var uri = IoUtils.resolve(securityManager, moduleKey, moduleSource.getUri());
return ModuleSource.uri(uri);
} else {
throw new PackageLoadError("cannotResolveDependencyNoProject");
}
} catch (URISyntaxException e) {
// impossible condition
throw PklBugException.unreachableCode();
} catch (IOException e) {
throw new VmExceptionBuilder()
.evalError("ioErrorLoadingModule", moduleSource.getUri())
.build();
} catch (ExternalReaderProcessException | SecurityManagerException | PackageLoadError e) {
throw new VmExceptionBuilder().withCause(e).build();
}
}
private <T> T doEvaluate(ModuleSource moduleSource, Function<VmTyped, T> doEvaluate) {
return doEvaluate(
() -> {
var moduleKey = moduleResolver.resolve(normalizeModuleSource(moduleSource));
var module = VmLanguage.get(null).loadModule(moduleKey);
return doEvaluate.apply(module);
});
}
private void handleTimeout(@Nullable TimeoutTask timeoutTask) {
if (timeoutTask == null || timeoutTask.cancel()) return;View on GitHub (pinned to f3efcbfc9b)
Solutions
- Verify the module URI exists and is readable (ls/check permissions, curl for remote URIs).
- Use an absolute or correctly project-rooted path; relative module paths resolve against the importing module or base URI.
- For remote modules, check network/proxy connectivity and retry.
- Catch PklException/VmException with this error code and surface a clear message naming the module URI.
Example fix
// before
evaluator.evaluate(OutputFormat.text(), Paths.get("config/pkls/Main.pkl"));
// after
Path p = Paths.get("config/pkls/Main.pkl");
if (!Files.isReadable(p)) throw new IllegalArgumentException("Module not readable: " + p);
evaluator.evaluate(OutputFormat.text(), p); Defensive patterns
Strategy: validation
Validate before calling
Path p = Paths.get("config/Main.pkl");
if (!Files.isRegularFile(p) || !Files.isReadable(p)) {
throw new IllegalStateException("Module unreadable: " + p.toAbsolutePath());
} Type guard
static boolean isLoadableModule(URI uri) {
try {
if ("file".equals(uri.getScheme())) return Files.isReadable(Paths.get(uri));
return uri.toURL().openConnection().getInputStream() != null; // remote probe
} catch (IOException e) { return false; }
} Try / catch
try {
evaluator.evaluateOutputText(source);
} catch (PklException e) {
if (e.getMessage().contains("ioErrorLoadingModule")) {
throw new IOException("Cannot load module: " + e.getMessage(), e);
}
throw e;
} Prevention
- Check file existence/readability before evaluate()
- Use absolute module paths or ModuleSource uris you control
- Pre-resolve remote/package modules (network check, dependency cache warm-up)
- Surface the module URI in user-facing error handling
When it happens
Trigger: Calling EvaluatorImpl to evaluate a module whose source cannot be read: a file:// module path that no longer exists or is unreadable, an https:// module whose fetch fails, or a package dependency module whose cached/remote content cannot be read. normalizeModuleSource catches IOException and rethrows as VmException with code ioErrorLoadingModule.
Common situations: Typo in the module path passed to evaluate(); reading a Pkl file deleted or moved after the URI was computed; network outage or proxy blocking a remote module; filesystem permission changes; container images missing files bundled at build time.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- ioErrorLoadingModule
- Is a directory
- cannotEvaluateNonFileBasedTestModule
- ioErrorWritingTestOutputFile
- ioErrorReadingTestOutputFile
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/a1b7d92356ba9629.
Report an issue: GitHub.