{"record":{"id":"d833fa2d287577d7","repo":"apache/druid","slug":"found-a-directory-on-path-s-please-use-deletere","errorCode":null,"errorMessage":"Found a directory on path[%s]. Please use deleteRecursively to delete dirs","messagePattern":"Found a directory on path\\[(.+?)\\]\\. Please use deleteRecursively to delete dirs","errorType":"validation","errorClass":"org.apache.druid.java.util.common.IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/storage/local/LocalFileStorageConnector.java","lineNumber":119,"sourceCode":"  {\n    File toWrite = fileWithBasePath(path);\n    FileUtils.mkdirp(toWrite.getParentFile());\n    return Files.newOutputStream(toWrite.toPath());\n  }\n\n  /**\n   * Deletes the file present at the location basePath + path. Throws an exception in case a dir is encountered.\n   *\n   * @param path input path\n   * @throws IOException thrown in case of errors.\n   */\n  @Override\n  public void deleteFile(String path) throws IOException\n  {\n    log.debug(\"Deleting file at path: [%s]\", path);\n    File toDelete = fileWithBasePath(path);\n    if (toDelete.isDirectory()) {\n      throw new IAE(StringUtils.format(\n          \"Found a directory on path[%s]. Please use deleteRecursively to delete dirs\", path));\n    }\n    Files.delete(fileWithBasePath(path).toPath());\n  }\n\n  /**\n   * Deletes the files present at each basePath + path. Throws an exception in case a dir is encountered.\n   *\n   * @param paths list of path to delete\n   * @throws IOException thrown in case of errors.\n   */\n  @Override\n  public void deleteFiles(Iterable<String> paths) throws IOException\n  {\n    for (String path : paths) {\n      log.debug(\"Deleting file at path: [%s]\", path);\n      deleteFile(path);\n    }","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/storage/local/LocalFileStorageConnector.java#L101-L137","documentation":"LocalFileStorageConnector.deleteFile only deletes regular files; if the path resolves to a directory it throws IAE telling the caller to use deleteRecursively instead. This guards against accidentally attempting Files.delete on directories, which would fail and could remove data unexpectedly.","triggerScenarios":"deleteFile(path) where the path under base path is an existing directory: passing a prefix/parent dir, empty-directory placeholders, or path computations that resolve to the base directory itself.","commonSituations":"Bulk delete jobs iterating paths that include directories; export destinations that create nested dirs whose parents are then passed to deleteFile; path normalization dropping the filename component.","solutions":["Use deleteRecursively(path) when the target may be a directory.","Check isDirectory before deleting and route accordingly in cleanup code.","Fix path-building logic so only concrete file paths (not prefixes/parents) reach deleteFile.","Add a pre-delete validation step in bulk cleanup jobs to skip or recurse into directories."],"exampleFix":"// before\nconnector.deleteFile(\"export/2024/\"); // directory\n// after\nFile target = new File(basePath, \"export/2024/\");\nif (target.isDirectory()) {\n  connector.deleteRecursively(\"export/2024/\");\n} else {\n  connector.deleteFile(\"export/2024/\");\n}","handlingStrategy":"validation","validationCode":"File f = new File(basePath, path);\nif (f.isDirectory()) { connector.deleteRecursively(path); } else if (f.exists()) { connector.deleteFile(path); }","typeGuard":"boolean isRegularFile(String p) { File f = new File(basePath, p); return f.exists() && !f.isDirectory(); }","tryCatchPattern":"try { connector.deleteFile(path); } catch (IllegalArgumentException e) { connector.deleteRecursively(path); }","preventionTips":["Only pass file paths (not prefixes) to deleteFile.","Prefer deleteRecursively for cleanup of unknown-shape trees.","Normalize paths to avoid dropping the filename component.","Log-and-skip directories in bulk delete loops instead of failing."],"tags":["local-storage","delete","directory"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}