{"record":{"id":"8339480384288a08","repo":"apache/hadoop","slug":"is-a-directory-833948","errorCode":null,"errorMessage":"{} is a directory","messagePattern":"(.+?) is a directory","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSFileSystem.java","lineNumber":705,"sourceCode":"      final Path f,\n      final FsPermission permission,\n      final boolean overwrite,\n      final int bufferSize,\n      final short replication,\n      final long blkSize,\n      final Progressable progress)\n      throws IOException {\n    String key = OBSCommonUtils.pathToKey(this, f);\n    FileStatus status;\n    long objectLen = 0;\n    try {\n      // get the status or throw an exception\n      status = getFileStatus(f);\n      objectLen = status.getLen();\n      // if the thread reaches here, there is something at the path\n      if (status.isDirectory()) {\n        // path references a directory: automatic error\n        throw new FileAlreadyExistsException(f + \" is a directory\");\n      }\n      if (!overwrite) {\n        // path references a file and overwrite is disabled\n        throw new FileAlreadyExistsException(f + \" already exists\");\n      }\n      LOG.debug(\"create: Overwriting file {}\", f);\n    } catch (FileNotFoundException e) {\n      // this means the file is not found\n      LOG.debug(\"create: Creating new file {}\", f);\n    }\n    return new FSDataOutputStream(\n        new OBSBlockOutputStream(\n            this,\n            key,\n            objectLen,\n            new SemaphoredDelegatingExecutor(\n                boundedMultipartUploadThreadPool,\n                blockOutputActiveBlocks, true),","sourceCodeStart":687,"sourceCodeEnd":723,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSFileSystem.java#L687-L723","documentation":"In OBSFileSystem.create(...), after getFileStatus succeeds, a directory at the target path is an unconditional error: the code throws FileAlreadyExistsException(f + ' is a directory'). Overwrite=true cannot help — overwriting a directory marker with a file is not a supported object-store operation here. This fires only when something directory-like actually exists at the key; a missing path proceeds to normal creation.","triggerScenarios":"Calling fs.create(path, ...) where path was previously created by mkdirs or by writing another object under it (implied directory); output paths colliding with existing directory structures (e.g. re-running a job whose outputDir itself is passed instead of outputDir/part-0); CreateFlag.OVERWRITE set but the existing entry is a directory.","commonSituations":"Specifying the MapReduce/Spark output directory itself as the output file; leftover directory markers from prior runs blocking new file creation; path normalization bugs that drop the filename and leave the parent directory as the target.","solutions":["Target the file path, not its parent directory (e.g. /out/part-r-00000, not /out)","Before create, if overwrite is on and the path is a directory, delete it: if (fs.exists(p) && fs.getFileStatus(p).isDirectory()) fs.delete(p, true)","Validate the target with getFileStatus and fail with a clear application error naming the conflicting directory","Clean stale output directories in job setup rather than reusing them as file targets"],"exampleFix":"// before\nfs.create(new Path(\"/job/out\"), true); // /job/out is an existing directory -> FileAlreadyExistsException\n\n// after\nPath out = new Path(\"/job/out\");\nif (fs.exists(out) && fs.getFileStatus(out).isDirectory()) {\n  fs.delete(out, true);\n}\nFSDataOutputStream os = fs.create(out, true);","handlingStrategy":"validation","validationCode":"if (fs.exists(f)) {\n  FileStatus st = fs.getFileStatus(f);\n  if (st.isDirectory()) {\n    if (overwrite) {\n      fs.delete(f, true); // only if semantically safe\n    } else {\n      throw new FileAlreadyExistsException(\"target is a directory: \" + f);\n    }\n  }\n}\nFSDataOutputStream out = fs.create(f, overwrite);","typeGuard":null,"tryCatchPattern":"try {\n  return fs.create(f, overwrite);\n} catch (FileAlreadyExistsException e) {\n  if (String.valueOf(e.getMessage()).endsWith(\"is a directory\")) {\n    // overwrite cannot fix this: delete the directory or pick a file path\n  }\n  throw e;\n}","preventionTips":["Point create() at the leaf file, never the output directory","Clean or version output paths between runs","Remember overwrite=true does NOT allow replacing a directory"],"tags":["path-misuse","file-vs-directory","create","hadoop-obs"],"backgroundTag":"file-already-exists","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}