{"record":{"id":"a714c1168b717f6d","repo":"GoogleContainerTools/jib","slug":"notdirectoryexception-directory","errorCode":null,"errorMessage":"NotDirectoryException: <directory>","messagePattern":"NotDirectoryException: <directory>","errorType":"validation","errorClass":"NotDirectoryException","httpStatus":null,"severity":"error","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/api/JavaContainerBuilder.java","lineNumber":683,"sourceCode":"      entrypoint.add(\"java\");\n      entrypoint.addAll(jvmFlags);\n      entrypoint.add(\"-cp\");\n      entrypoint.add(classpathString);\n      entrypoint.add(mainClass);\n      jibContainerBuilder.setEntrypoint(entrypoint);\n    }\n\n    return jibContainerBuilder;\n  }\n\n  private JavaContainerBuilder addDirectory(\n      List<PathPredicatePair> addedPaths, Path directory, Predicate<Path> filter)\n      throws NoSuchFileException, NotDirectoryException {\n    if (!Files.exists(directory)) {\n      throw new NoSuchFileException(directory.toString());\n    }\n    if (!Files.isDirectory(directory)) {\n      throw new NotDirectoryException(directory.toString());\n    }\n    addedPaths.add(new PathPredicatePair(directory, filter));\n    return this;\n  }\n\n  private void addFileToLayer(\n      Map<LayerType, FileEntriesLayer.Builder> layerBuilders,\n      LayerType layerType,\n      Path sourceFile,\n      AbsoluteUnixPath pathInContainer) {\n    if (!layerBuilders.containsKey(layerType)) {\n      layerBuilders.put(layerType, FileEntriesLayer.builder());\n    }\n    Instant modificationTime = modificationTimeProvider.get(sourceFile, pathInContainer);\n    layerBuilders.get(layerType).addEntry(sourceFile, pathInContainer, modificationTime);\n  }\n\n  private void addDirectoryContentsToLayer(","sourceCodeStart":665,"sourceCodeEnd":701,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/api/JavaContainerBuilder.java#L665-L701","documentation":"JavaContainerBuilder.addDirectory requires the given path to be a directory. After confirming existence, it checks Files.isDirectory(); if the path exists but is a regular file (or other non-directory), it throws NotDirectoryException naming the path. This prevents users from passing file paths where layer directories are expected.","triggerScenarios":"Calling addResources(Path)/addClasses(Path)/addDependencies(Path) (or addDirectory) with a Path that points to a regular file, e.g. passing an archive file or an individual class/resource file instead of its containing directory.","commonSituations":"Passing target/classes/SomeClass.class instead of target/classes; passing an app.jar where an exploded directory is expected; symlink resolution turning a directory path into a file; wrong variable holding a config file path.","solutions":["Check the path with Files.isDirectory(path) before calling; point to the directory, not a file.","If you want to add an individual file, use the file-oriented API (e.g. JavaContainerBuilder addToLayer / addFileToLayer path) instead of addDirectory.","Remove or fix symlinks that resolve to files; ensure the path is the layer root directory.","Unpack archives (jar/zip) to a directory if you intended to add their contents as a directory layer."],"exampleFix":"// before\nbuilder.addClasses(Paths.get(\"target/classes/com/app/Main.class\"));\n// after\nPath classes = Paths.get(\"target/classes\");\nif (!Files.isDirectory(classes)) { throw new IllegalStateException(\"not a directory: \" + classes); }\nbuilder.addClasses(classes);","handlingStrategy":"validation","validationCode":"if (Files.exists(dir) && !Files.isDirectory(dir)) throw new IllegalArgumentException(\"Not a directory: \" + dir);","typeGuard":"boolean isDirectory(Path p) { return p != null && Files.isDirectory(p); }","tryCatchPattern":"try { builder.addClasses(dir); } catch (NotDirectoryException e) { log.error(\"Path is a file, not a directory: {}\", e.getFile()); throw new BuildSetupException(e); }","preventionTips":["Never pass .class/.jar/config files where a directory is expected","Resolve symlinks with toRealPath() before checking","Use file APIs for individual files and directory APIs for layers","Unit-test container builder setup against a prepared temp directory"],"tags":["filesystem","path","container-build"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}