{"record":{"id":"81c45234c04c7b3f","repo":"apache/hadoop","slug":"item-not-found-s-81c452","errorCode":null,"errorMessage":"Item not found: %s","messagePattern":"Item not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorageFileSystem.java","lineNumber":242,"sourceCode":"    }\n\n    // Create only a leaf directory because subdirectories will be inferred\n    // if leaf directory exists\n    try {\n      gcs.createEmptyObject(resourceId);\n    } catch (FileAlreadyExistsException e) {\n      // This means that directory object already exist, and we do not need to do anything.\n      LOG.trace(\"mkdirs: {} already exists, ignoring creation failure\", resourceId, e);\n    }\n  }\n\n  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<>();","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorageFileSystem.java#L224-L260","documentation":"GoogleCloudStorageFileSystem.delete throws FileNotFoundException(\"Item not found: <path>\") when getFileInfo(path).exists() is false — deleting something that is not there. Deleting the gs:// root is rejected earlier by checkArgument. The exists-check and the actual delete are separate calls, so a path can also vanish between stat and delete.","triggerScenarios":"delete(path, recursive) for a nonexistent object, bucket, or directory; concurrent deletion by another client between your listing and your delete; retrying a job whose earlier attempt already deleted the path.","commonSituations":"Concurrent cleanup jobs racing each other; committer cleanup removing temp files a retried task also tries to delete; typo'd paths; idempotent job retries.","solutions":["Treat FileNotFoundException from delete as success where delete-idempotency is the goal.","Pre-check with getFileInfo(path).exists() for clearer control flow (still combine with catching, due to the race window).","Fix ordering/ownership in cleanup logic so only one writer deletes a given path."],"exampleFix":"// before\nfs.delete(path, true); // throws if already gone\n\n// after\ntry {\n  fs.delete(path, true);\n} catch (FileNotFoundException e) {\n  // already deleted by someone else: idempotent success\n}","handlingStrategy":"validation","validationCode":"if (gcsFs.getFileInfo(path).exists()) {\n  gcsFs.delete(path, recursive);\n} else {\n  LOG.debug(\"delete skipped, already gone: {}\", path);\n}","typeGuard":null,"tryCatchPattern":"catch (FileNotFoundException e) {\n  // someone else removed it first: treat as success for idempotent cleanup\n}","preventionTips":["Design cleanup as idempotent: missing path == success.","Ensure a single owner deletes each path; serialize competing cleanup jobs.","Log deleted paths to make retried-delete races diagnosable."],"tags":["gcs","delete","filenotfound","idempotency","race-condition"],"backgroundTag":"delete-nonexistent-path","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}