{"record":{"id":"63b08772062279c9","repo":"apache/hadoop","slug":"directory-f-tostring-is-not-empty","errorCode":null,"errorMessage":"Directory \" + f.toString() + \" is not empty","messagePattern":"Directory \" \\+ f\\.toString\\(\\) \\+ \" is not empty","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java","lineNumber":800,"sourceCode":"  /**\n   * Delete the given path to a file or directory.\n   * @param p the path to delete\n   * @param recursive to delete sub-directories\n   * @return true if the file or directory and all its contents were deleted\n   * @throws IOException if p is non-empty and recursive is false \n   */\n  @Override\n  public boolean delete(Path p, boolean recursive) throws IOException {\n    File f = pathToFile(p);\n    if (!f.exists()) {\n      //no path, return false \"nothing to delete\"\n      return false;\n    }\n    if (f.isFile()) {\n      return f.delete();\n    } else if (!recursive && f.isDirectory() && \n        (FileUtil.listFiles(f).length != 0)) {\n      throw new IOException(\"Directory \" + f.toString() + \" is not empty\");\n    }\n    return FileUtil.fullyDelete(f);\n  }\n \n  /**\n   * {@inheritDoc}\n   *\n   * (<b>Note</b>: Returned list is not sorted in any given order,\n   * due to reliance on Java's {@link File#list()} API.)\n   */\n  @Override\n  public FileStatus[] listStatus(Path f) throws IOException {\n    File localf = pathToFile(f);\n    FileStatus[] results;\n\n    if (!localf.exists()) {\n      throw new FileNotFoundException(\"File \" + f + \" does not exist\");\n    }","sourceCodeStart":782,"sourceCodeEnd":818,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java#L782-L818","documentation":"RawLocalFileSystem.delete(Path, recursive=false) throws IOException('Directory ... is not empty') when the target is a directory containing entries. Non-recursive delete is deliberately safe: it removes only empty directories and files. The check uses FileUtil.listFiles, so even hidden dotfiles count as content.","triggerScenarios":"Calling fs.delete(dirPath, false) on a directory with any children: cleaning a job output directory non-recursively, attempting to remove a directory that contains hidden .tmp/.crc files, or racing with a writer that added a file between listing and delete.","commonSituations":"Cleanup code that assumed the directory was empty, Hadoop's per-file .crc checksum sidecar files (e.g. .part-00000.crc) keeping a 'visually empty' directory non-empty, or temp directories with dot-prefixed files.","solutions":["Pass recursive=true when full cleanup is intended: fs.delete(dir, true).","List first if selective deletion is needed: delete children individually, then remove the (now empty) directory with recursive=false.","Check for hidden files: ls -la the directory; remove .crc/_SUCCESS/_temporary leftovers explicitly.","Handle the race by catching IOException and re-checking emptiness rather than blindly retrying."],"exampleFix":"// before\nfs.delete(new Path(\"/out\"), false); // throws: contains part files / .crc files\n\n// after\nboolean removed = fs.delete(new Path(\"/out\"), true);","handlingStrategy":"validation","validationCode":"if (fs.getFileStatus(dir).isDirectory()\n      && fs.listStatus(dir).length > 0 && !recursive) {\n  throw new IllegalStateException(dir + \" not empty; pass recursive=true or clear it\");\n}\nfs.delete(dir, recursive);","typeGuard":null,"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); // fall back to recursive when full cleanup is safe\n  } else {\n    throw e;\n  }\n}","preventionTips":["Choose recursive delete deliberately at the call site instead of defaulting to false everywhere.","Remember hidden files (.crc sidecars, dotfiles) count as content.","For selective cleanup, delete children individually then remove the empty dir."],"tags":["hadoop","local-filesystem","delete","directory-not-empty","cleanup"],"backgroundTag":"directory-not-empty","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}