{"record":{"id":"3dcb1bcf970ccbbf","repo":"apache/hadoop","slug":"cannot-delete-a-non-empty-directory-s","errorCode":null,"errorMessage":"Cannot delete a non-empty directory. : %s","messagePattern":"Cannot delete a non-empty directory\\. : (.+?)","errorType":"exception","errorClass":"DirectoryNotEmptyException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorageFileSystem.java","lineNumber":254,"sourceCode":"  void delete(URI path, boolean recursive) throws IOException {\n    checkNotNull(path, \"path should not be null\");\n    checkArgument(!path.equals(GCSROOT), \"Cannot delete root path (%s)\", path);\n\n    FileInfo fileInfo = getFileInfo(path);\n    if (!fileInfo.exists()) {\n      throw new FileNotFoundException(\"Item not found: \" + path);\n    }\n\n    List<FileInfo> itemsToDelete;\n    // Delete sub-items if it is a directory.\n    if (fileInfo.isDirectory()) {\n      itemsToDelete =\n          recursive\n              ? listRecursive(fileInfo.getPath()) // TODO: Get only one result\n              : listDirectory(fileInfo.getPath());\n\n      if (!itemsToDelete.isEmpty() && !recursive) {\n        throw new DirectoryNotEmptyException(\"Cannot delete a non-empty directory. : \" + path);\n      }\n    } else {\n      itemsToDelete = new ArrayList<>();\n    }\n\n    List<FileInfo> bucketsToDelete = new ArrayList<>();\n    (fileInfo.getItemInfo().isBucket() ? bucketsToDelete : itemsToDelete).add(fileInfo);\n\n    deleteObjects(itemsToDelete, bucketsToDelete);\n\n    StorageResourceId parentId =\n        StorageResourceId.fromUriPath(UriPaths.getParentPath(path), true);\n    GoogleCloudStorageItemInfo parentInfo =\n        getFileInfoInternal(parentId, /* inferImplicitDirectories= */ false);\n\n    StorageResourceId resourceId = parentInfo.getResourceId();\n    if (parentInfo.exists()\n        || resourceId.isRoot()","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorageFileSystem.java#L236-L272","documentation":"delete(path, recursive=false) lists the directory (listDirectory) and throws DirectoryNotEmptyException if any children exist — objects under the prefix and/or explicit directory-marker objects. Recursive delete uses listRecursive and removes everything instead. This mirrors the Hadoop FileSystem.delete(non-recursive) contract: fail rather than silently partial-delete.","triggerScenarios":"FileSystem.delete(path, false) on a GCS directory containing anything: real data objects, _SUCCESS/.crc markers, or empty directory placeholders from mkdirs.","commonSituations":"Job cleanup calling delete(dir, false) as an existence/emptiness check; accidental non-recursive flag; a directory that 'looks empty' but hides _SUCCESS, .crc, or dot-files.","solutions":["Pass recursive=true when the intent is to remove the directory and its contents.","If the non-recursive contract matters, first list the directory and surface a precise 'not empty: <children>' error.","Check for hidden children (_SUCCESS, .crc, empty markers) before concluding a directory should be deletable."],"exampleFix":"// before\nfs.delete(dirPath, false); // DirectoryNotEmptyException\n\n// after\nFileStatus[] children = fs.listStatus(dirPath);\nif (children.length == 0) {\n  fs.delete(dirPath, false);\n} else {\n  fs.delete(dirPath, true); // or fail with a domain-specific message\n}","handlingStrategy":"validation","validationCode":"if (fileInfo.isDirectory() && !recursive) {\n  List<FileInfo> children = gcsFs.listDirectory(fileInfo.getPath());\n  if (!children.isEmpty()) {\n    throw new NonEmptyDirectoryException(path, children); // actionable message\n  }\n}\ngcsFs.delete(path, recursive);","typeGuard":null,"tryCatchPattern":"catch (DirectoryNotEmptyException e) {\n  // decide policy: escalate to recursive delete, or report children to the user\n}","preventionTips":["Pass recursive=true when the intent is to remove contents.","List before non-recursive delete to produce precise 'blocked by X' errors.","Remember hidden children (_SUCCESS, .crc, markers) count as non-empty."],"tags":["gcs","delete","directory-not-empty","recursive-delete"],"backgroundTag":"directory-not-empty","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}