apple/pkl · error · IOException
Is a directory
Error message
Is a directory
What it means
Raised in `PackageResolvers` `getBytes` when code attempts to read the bytes of a package element that is actually a directory (it has child elements rather than file content). The resolver throws `fileIsADirectory()` ("Is a directory") instead of returning bytes, because directories inside a package have no byte payload.
Solutions
- Point the path at a concrete file inside the package, not a directory.
- List elements first (e.g. `listElements`/`readGlob`) and pick a specific file.
- Append the missing trailing segment (e.g. `dir/` + `file.pkl`) to the URI.
- If you need directory contents, iterate the children keys rather than reading the directory itself.
Example fix
// before
bytes = read("pkg://example.com/my-pkg@1.0.0#/src")
// after
bytes = read("pkg://example.com/my-pkg@1.0.0#/src/config.pkl") Defensive patterns
Strategy: validation
Validate before calling
function assertNotDirectory(pkgUri, path) {
if (listElements(pkgUri).includes(path) && path.split("/").pop() === "") {
throw new Error(`${path} is a directory; point at a file`);
}
} Type guard
function isFileElement(pkgUri, path) { return !path.endsWith("/") && listElements(pkgUri).some(e => e === path); } Try / catch
try {
const bytes = getBytes(pkgUri, path);
} catch (e) {
if (e.code === "IsADirectory") { /* list elements and pick a file */ }
} Prevention
- Always end package element paths with a concrete file name.
- List or glob package elements before reading.
- Treat `pkg:` paths as file paths, not directory trees to concatenate.
When it happens
Trigger: Calling the package/resource resolution API with an element path that resolves to a directory node in the package's element tree — e.g. `read("pkg:/some/dir")` or a programmatic `getBytes` on a path ending at a folder, or a path missing the final filename segment.
Common situations: Treating `pkg:` URIs like filesystem paths and omitting the file name; expecting a directory listing or concatenation from `read` on a folder; typos where the path points at a parent directory of the intended file.
Related errors
- cannotEvaluateNonFileBasedTestModule
- cannotFindModule
- Failed to write to $depsFile
- invalidOutputFileStructure
- invalidPackageZipUrl
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/b8958e2cfbb6f092.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-core/src/main/java/org/pkl/core/packages/PackageResolvers.java:346
throws IOException, SecurityManagerException {
var packageUri = uri.getPackageUri();
ensurePackageDownloaded(packageUri, checksums);
TreePathElement elem;
synchronized (lock) {
elem = cachedTreePathElementRoots.get(uri.getPackageUri()).getElement(uri.getAssetPath());
}
if (elem == null) {
throw new FileNotFoundException();
} else if (elem.isDirectory()) {
if (allowDirectories) {
var text =
StreamSupport.stream(elem.getChildren().getKeys().spliterator(), false)
.sorted()
.collect(Collectors.joining("\n"))
+ "\n";
return text.getBytes(StandardCharsets.UTF_8);
}
throw fileIsADirectory();
}
EconomicMap<String, ByteBuffer> entries;
synchronized (lock) {
entries = cachedEntries.get(packageUri);
}
// need to normalize here but not in `doListElements` nor `doHasElement` because
// `TreePathElement.getElement` does normalization already.
var path = IoUtils.toNormalizedPathString(Path.of(uri.getAssetPath()).normalize());
return entries.get(path).array();
}
@Override
public List<PathElement> doListElements(PackageAssetUri uri, @Nullable Checksums checksums)
throws IOException, SecurityManagerException {
var packageUri = uri.getPackageUri();
ensurePackageDownloaded(packageUri, checksums);
TreePathElement element;
synchronized (lock) {View on GitHub (pinned to f3efcbfc9b)