apple/pkl · error · IOException
Is a directory
Error message
Is a directory
What it means
The message 'Is a directory' is produced by ResolvedModuleKeys.loadSource (LocalPathModuleKey) when reading a module resolves to a directory rather than a file. On Windows, reading a directory throws AccessDeniedException, so the code checks Files.isDirectory(path) and rethrows a uniform IOException('Is a directory') to sync the error message across operating systems. This indicates a module URI/path pointed at a directory instead of a file.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/module/ResolvedModuleKeys.java:111
@Override
public URI getUri() {
return uri;
}
@Override
public String loadSource() throws IOException {
try {
if (nofollow) {
try (var in = Files.newInputStream(path, LinkOption.NOFOLLOW_LINKS)) {
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}
}
return Files.readString(path, StandardCharsets.UTF_8);
} catch (AccessDeniedException e) {
// Windows throws `AccessDeniedException` when reading directories.
// Sync error between different OSes.
if (Files.isDirectory(path)) {
throw new IOException("Is a directory");
}
throw e;
}
}
}
private static class Url implements ResolvedModuleKey {
final ModuleKey original;
final URI uri;
final URL url;
Url(ModuleKey original, URI uri, URL url) {
this.original = original;
this.uri = uri;
this.url = url;
}
@OverrideView on GitHub (pinned to f3efcbfc9b)
Solutions
- Point the import/path at the actual .pkl file, e.g. `import "dir/module.pkl"` instead of `import "dir"`.
- Verify with `ls`/`Get-Item` that the resolved path is a regular file, not a directory.
- If a symlink is involved, retarget it to a file.
- Fix any tooling or templating that generated the truncated path.
Example fix
// before import "file:///home/me/project/shared" // after import "file:///home/me/project/shared/config.pkl"
Defensive patterns
Strategy: validation
Validate before calling
import java.nio.file.*;
Path p = Path.of("/home/me/project/shared");
if (!Files.isRegularFile(p)) throw new IllegalArgumentException("Module path must be a file, got: " + (Files.isDirectory(p) ? "directory" : p)); Prevention
- Always point imports at an explicit .pkl file, not a directory.
- Verify generated paths end with a filename before passing them to the module loader.
- Be aware error text is OS-synced: 'Is a directory' also appears on Windows for directory paths.
- Check symlinks resolve to regular files.
When it happens
Trigger: Calling loadSource on a local-path module key whose path is a directory — e.g. an import pointing at a folder (`import "file:///some/dir"`) or ProjectDepsManager loading a deps URI that resolves to a directory.
Common situations: Typing an import path without the filename (expecting index.pkl resolution that isn't supported); a path truncated mid-edit; symlinked or mount-point directories mistaken for files; a deps file placeholder directory in CI.
Related errors
- cannotEvaluateNonFileBasedTestModule
- ioErrorLoadingModule
- Failed to convert `pkl.base#String` to `java.nio.file.Path`.
- ioErrorLoadingModule
- resourcePastRootDir|modulePastRootDir
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/2b0233666093f263.
Report an issue: GitHub.