{"record":{"id":"0d4b2d1ebb302721","repo":"apache/hadoop","slug":"not-a-directory-0d4b2d","errorCode":null,"errorMessage":"Not a directory: {}","messagePattern":"Not 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":856,"sourceCode":"   * @param replication required block replication for the file\n   * @param blkSize     block size\n   * @param progress    the progress reporter\n   * @throws IOException IO failure\n   */\n  @Override\n  public FSDataOutputStream createNonRecursive(\n      final Path path,\n      final FsPermission permission,\n      final EnumSet<CreateFlag> flags,\n      final int bufferSize,\n      final short replication,\n      final long blkSize,\n      final Progressable progress)\n      throws IOException {\n    Path parent = path.getParent();\n    if (parent != null && !getFileStatus(parent).isDirectory()) {\n      // expect this to raise an exception if there is no parent\n      throw new FileAlreadyExistsException(\"Not a directory: \" + parent);\n    }\n    return create(\n        path,\n        permission,\n        flags.contains(CreateFlag.OVERWRITE),\n        bufferSize,\n        replication,\n        blkSize,\n        progress);\n  }\n\n  /**\n   * Append to an existing file (optional operation).\n   *\n   * @param f          the existing file to be appended\n   * @param bufferSize the size of the buffer to be used\n   * @param progress   for reporting progress if it is not null\n   * @throws IOException indicating that append is not supported","sourceCodeStart":838,"sourceCodeEnd":874,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSFileSystem.java#L838-L874","documentation":"OBSFileSystem.createNonRecursive resolves the parent path and requires it to be an existing directory: if parent != null and !getFileStatus(parent).isDirectory(), it throws FileAlreadyExistsException('Not a directory: ' + parent). Note getFileStatus on a missing parent throws FileNotFoundException first, so this specific message fires when the parent exists as a FILE. The non-recursive contract demands the parent already exist as a directory; the connector does not create intermediate directories.","triggerScenarios":"Calling createNonRecursive where the parent path is occupied by a regular object (e.g. /a is a file, creating /a/b.txt); file/leaf names colliding with existing object keys used as parents; frameworks using non-recursive create (e.g. some output committers, HBase) against paths whose parents were never mkdir'd or were written as files.","commonSituations":"Nested output layouts where an earlier step wrote a file at what later becomes a directory level ('file blocks directory' pattern); race between a writer creating /a as a file and another writing /a/b; porting recursive-create code to non-recursive without pre-creating parents.","solutions":["Ensure parent directories exist before the call: if (!fs.exists(parent)) fs.mkdirs(parent)","If the parent is a stray file, delete or rename it first: fs.delete(parent, false) then mkdirs","Check the layout invariant before the job: no path may be used both as a file key and as a directory prefix","Prefer the recursive create(...) when intermediate directory creation is acceptable"],"exampleFix":"// before\nfs.createNonRecursive(new Path(\"/a/b.txt\"), perm, flags, bufSize, repl, blkSize, null);\n// /a exists as a FILE -> FileAlreadyExistsException: Not a directory: /a\n\n// after\nPath parent = new Path(\"/a\");\nif (fs.exists(parent) && !fs.getFileStatus(parent).isDirectory()) {\n  fs.delete(parent, false);\n}\nif (!fs.exists(parent)) {\n  fs.mkdirs(parent);\n}\nfs.createNonRecursive(new Path(parent, \"b.txt\"), perm, flags, bufSize, repl, blkSize, null);","handlingStrategy":"validation","validationCode":"Path parent = path.getParent();\nif (parent != null) {\n  if (fs.exists(parent)) {\n    if (!fs.getFileStatus(parent).isDirectory()) {\n      throw new FileAlreadyExistsException(\"parent occupied by a file: \" + parent);\n    }\n  } else {\n    fs.mkdirs(parent);\n  }\n}\nfs.createNonRecursive(path, ...);","typeGuard":null,"tryCatchPattern":"try {\n  fs.createNonRecursive(path, ...);\n} catch (FileAlreadyExistsException e) {\n  if (String.valueOf(e.getMessage()).startsWith(\"Not a directory\")) {\n    // parent is a file: relocate or delete it, mkdirs, then retry\n  }\n  throw e;\n}","preventionTips":["mkdir parents before non-recursive create, or use recursive create","Enforce the layout invariant: no key used both as file and directory prefix","Check parent status explicitly when coming from HDFS-style code"],"tags":["create","parent-directory","file-vs-directory","hadoop-obs"],"backgroundTag":"parent-not-a-directory","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}