{"record":{"id":"e633e48ef476c3c2","repo":"apache/hadoop","slug":"path-is-a-file-e633e4","errorCode":null,"errorMessage":"Path is a file: {}","messagePattern":"Path is a file: (.+?)","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java","lineNumber":470,"sourceCode":"\n  @Override\n  public Path getWorkingDirectory() {\n    return workingDir;\n  }\n\n  @Override\n  public void setWorkingDirectory(Path newDir) {\n    this.workingDir = newDir;\n  }\n\n  @Override\n  public boolean mkdirs(Path path, FsPermission permission) throws IOException {\n    try {\n      FileStatus fileStatus = innerFileStatus(path);\n      if (fileStatus.isDirectory()) {\n        return true;\n      } else {\n        throw new FileAlreadyExistsException(\"Path is a file: \" + path);\n      }\n    } catch (FileNotFoundException e) {\n      Path dir = makeQualified(path);\n      validatePath(dir);\n      fsOps.mkdirs(dir);\n    }\n    return true;\n  }\n\n  private void validatePath(Path path) throws IOException {\n    Path parent = path.getParent();\n    do {\n      try {\n        FileStatus fileStatus = innerFileStatus(parent);\n        if (fileStatus.isDirectory()) {\n          // If path exists and a directory, exit\n          break;\n        } else {","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java#L452-L488","documentation":"mkdirs() throws FileAlreadyExistsException(\"Path is a file: ...\") when the path to create already exists as a file/object. The Hadoop contract requires mkdirs over an existing file to fail (mkdirs over an existing directory returns true).","triggerScenarios":"fs.mkdirs(path) where innerFileStatus(path) resolves to an existing file object, e.g. an object 'data/part-0' was written and the job now tries mkdirs('data/part-0').","commonSituations":"Path scheme collisions between file outputs and directory outputs (writing a file where a directory is later expected); re-running pipelines after a partial failure left a file at the directory location; Hive/Spark partition paths that were previously written as files.","solutions":["Delete or rename the conflicting file object before creating the directory","Fix path construction so files and directories never share the same key","Check first: if (fs.exists(p) && fs.getFileStatus(p).isFile()) handle the collision explicitly"],"exampleFix":"// before\nfs.mkdirs(new Path(\"/data/export\")); // /data/export exists as a file -> exception\n\n// after\nPath p = new Path(\"/data/export\");\nif (fs.exists(p) && fs.getFileStatus(p).isFile()) { fs.delete(p, false); }\nfs.mkdirs(p);","handlingStrategy":"validation","validationCode":"if (fs.exists(p)) {\n  if (!fs.getFileStatus(p).isDirectory()) {\n    throw new IllegalStateException(\"file occupies directory path: \" + p);\n  }\n} else {\n  fs.mkdirs(p);\n}","typeGuard":null,"tryCatchPattern":"try { fs.mkdirs(p); }\ncatch (FileAlreadyExistsException e) {\n  // path occupied by a file: relocate or delete, then retry\n}","preventionTips":["Keep file keys and directory prefixes disjoint by design","Check exists+isDirectory before mkdirs in reusable helpers","After partial failures, sweep for files at expected directory paths"],"tags":["mkdirs","file-already-exists","path-collision","tos"],"backgroundTag":"parent-not-a-directory","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}