{"record":{"id":"62b358436bc90cf5","repo":"apache/hadoop","slug":"directory-file-is-not-empty","errorCode":null,"errorMessage":"Directory: {file} is not empty.","messagePattern":"Directory: (.+?) is not empty\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPFileSystem.java","lineNumber":432,"sourceCode":"   * the overhead of opening/closing a TCP connection.\n   */\n  private boolean delete(FTPClient client, Path file, boolean recursive)\n      throws IOException {\n    Path workDir = new Path(client.printWorkingDirectory());\n    Path absolute = makeAbsolute(workDir, file);\n    String pathName = absolute.toUri().getPath();\n    try {\n      FileStatus fileStat = getFileStatus(client, absolute);\n      if (fileStat.isFile()) {\n        return client.deleteFile(pathName);\n      }\n    } catch (FileNotFoundException e) {\n      //the file is not there\n      return false;\n    }\n    FileStatus[] dirEntries = listStatus(client, absolute);\n    if (dirEntries != null && dirEntries.length > 0 && !(recursive)) {\n      throw new IOException(\"Directory: \" + file + \" is not empty.\");\n    }\n    for (FileStatus dirEntry : dirEntries) {\n      delete(client, new Path(absolute, dirEntry.getPath()), recursive);\n    }\n    return client.removeDirectory(pathName);\n  }\n\n  @VisibleForTesting\n  FsAction getFsAction(int accessGroup, FTPFile ftpFile) {\n    FsAction action = FsAction.NONE;\n    if (ftpFile.hasPermission(accessGroup, FTPFile.READ_PERMISSION)) {\n      action = action.or(FsAction.READ);\n    }\n    if (ftpFile.hasPermission(accessGroup, FTPFile.WRITE_PERMISSION)) {\n      action = action.or(FsAction.WRITE);\n    }\n    if (ftpFile.hasPermission(accessGroup, FTPFile.EXECUTE_PERMISSION)) {\n      action = action.or(FsAction.EXECUTE);","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPFileSystem.java#L414-L450","documentation":"delete(path, recursive=false) lists the directory first; if it contains any entries and recursion is off, deletion is refused with this IOException rather than silently dropping content. Only delete(path, true) walks and removes children.","triggerScenarios":"fs.delete(dir, false) on a non-empty FTP directory; cleanup code assuming the directory is empty; hidden entries (dotfiles, subdirectories) making a directory look empty to the user.","commonSituations":"Job cleanup expecting an empty output dir; FTP servers that list hidden files; shared upload directories that accumulate entries between runs.","solutions":["Call fs.delete(path, true) when recursive deletion is intended","If only empty directories should be removed, check fs.listStatus(dir).length == 0 first and skip otherwise","List the directory to see what entries exist — dotfiles count as entries"],"exampleFix":"// before\nfs.delete(dir, false); // IOException: Directory: ... is not empty.\n\n// after\nif (fs.getFileStatus(dir).isDirectory() && fs.listStatus(dir).length > 0) {\n  boolean ok = fs.delete(dir, true); // recursive delete intended\n} else {\n  fs.delete(dir, false);\n}","handlingStrategy":"validation","validationCode":"if (fs.getFileStatus(dir).isDirectory() && fs.listStatus(dir).length > 0) {\n  boolean removed = fs.delete(dir, true); // explicit recursive decision\n} else {\n  fs.delete(dir, false);\n}","typeGuard":"static boolean isEmptyDirectory(FileSystem fs, Path p) throws IOException {\n  FileStatus st = fs.getFileStatus(p);\n  return st.isDirectory() && fs.listStatus(p).length == 0;\n}","tryCatchPattern":"try {\n  fs.delete(dir, false);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"not empty\")) {\n    fs.delete(dir, true); // only if recursive delete is acceptable\n  } else {\n    throw e;\n  }\n}","preventionTips":["Pass recursive=true deliberately when bulk deletion is intended","Before deleting 'empty' dirs, listStatus them — hidden dotfiles still count as entries"],"tags":["ftp","delete","directory-not-empty"],"backgroundTag":"directory-not-empty","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}