{"record":{"id":"b8958e2cfbb6f092","repo":"apple/pkl","slug":"is-a-directory-b8958e","errorCode":null,"errorMessage":"Is a directory","messagePattern":"Is a directory","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/packages/PackageResolvers.java","lineNumber":346,"sourceCode":"        throws IOException, SecurityManagerException {\n      var packageUri = uri.getPackageUri();\n      ensurePackageDownloaded(packageUri, checksums);\n      TreePathElement elem;\n      synchronized (lock) {\n        elem = cachedTreePathElementRoots.get(uri.getPackageUri()).getElement(uri.getAssetPath());\n      }\n      if (elem == null) {\n        throw new FileNotFoundException();\n      } else if (elem.isDirectory()) {\n        if (allowDirectories) {\n          var text =\n              StreamSupport.stream(elem.getChildren().getKeys().spliterator(), false)\n                      .sorted()\n                      .collect(Collectors.joining(\"\\n\"))\n                  + \"\\n\";\n          return text.getBytes(StandardCharsets.UTF_8);\n        }\n        throw fileIsADirectory();\n      }\n      EconomicMap<String, ByteBuffer> entries;\n      synchronized (lock) {\n        entries = cachedEntries.get(packageUri);\n      }\n      // need to normalize here but not in `doListElements` nor `doHasElement` because\n      // `TreePathElement.getElement` does normalization already.\n      var path = IoUtils.toNormalizedPathString(Path.of(uri.getAssetPath()).normalize());\n      return entries.get(path).array();\n    }\n\n    @Override\n    public List<PathElement> doListElements(PackageAssetUri uri, @Nullable Checksums checksums)\n        throws IOException, SecurityManagerException {\n      var packageUri = uri.getPackageUri();\n      ensurePackageDownloaded(packageUri, checksums);\n      TreePathElement element;\n      synchronized (lock) {","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/packages/PackageResolvers.java#L328-L364","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbytes = read(\"pkg://example.com/my-pkg@1.0.0#/src\")\n// after\nbytes = read(\"pkg://example.com/my-pkg@1.0.0#/src/config.pkl\")","handlingStrategy":"validation","validationCode":"function assertNotDirectory(pkgUri, path) {\n  if (listElements(pkgUri).includes(path) && path.split(\"/\").pop() === \"\") {\n    throw new Error(`${path} is a directory; point at a file`);\n  }\n}","typeGuard":"function isFileElement(pkgUri, path) { return !path.endsWith(\"/\") && listElements(pkgUri).some(e => e === path); }","tryCatchPattern":"try {\n  const bytes = getBytes(pkgUri, path);\n} catch (e) {\n  if (e.code === \"IsADirectory\") { /* list elements and pick a file */ }\n}","preventionTips":["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."],"tags":["pkl","packages","filesystem","directory"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}