{"record":{"id":"89ccf6ccbe3972a7","repo":"apache/hadoop","slug":"dst-tostring","errorCode":null,"errorMessage":"dst.toString()","messagePattern":"dst\\.toString\\(\\)","errorType":"exception","errorClass":"PathIsDirectoryException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java","lineNumber":621,"sourceCode":"      return true;\n    }\n  }\n\n  private static Path checkDest(String srcName, FileSystem dstFS, Path dst,\n      boolean overwrite) throws IOException {\n    FileStatus sdst;\n    try {\n      sdst = dstFS.getFileStatus(dst);\n    } catch (FileNotFoundException e) {\n      sdst = null;\n    }\n    if (null != sdst) {\n      if (sdst.isDirectory()) {\n        if (null == srcName) {\n          if (overwrite) {\n            return dst;\n          }\n          throw new PathIsDirectoryException(dst.toString());\n        }\n        return checkDest(null, dstFS, new Path(dst, srcName), overwrite);\n      } else if (!overwrite) {\n        throw new PathExistsException(dst.toString(),\n            \"Target \" + dst + \" already exists\");\n      }\n    }\n    return dst;\n  }\n\n  public static boolean isRegularFile(File file) {\n    return isRegularFile(file, true);\n  }\n\n  /**\n   * Check if the file is regular.\n   * @param file The file being checked.\n   * @param allowLinks Whether to allow matching links.","sourceCodeStart":603,"sourceCodeEnd":639,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java#L603-L639","documentation":"checkDest() throws PathIsDirectoryException(dst.toString()) when the resolved destination path on dstFS already exists as a directory and overwrite is false and there is no source name to join onto it (srcName == null). PathIsDirectoryException extends IOException, so it surfaces as a normal IO error from FileUtil.copy. The message body is just the destination path string. It means 'you asked to write a file where a directory stands'.","triggerScenarios":"FileUtil.copy(File src, FileSystem dstFS, Path dst, false, conf) where dst (or dst/srcName via the recursive checkDest(null, ...) call) resolves to an existing directory; checkDest recursing into new Path(dst, srcName) that collides with a pre-existing subdirectory of the same name.","commonSituations":"Uploading a file named 'conf' into an HDFS dir that already contains a directory 'conf'; CI jobs re-running a put without -f semantics; passing an HDFS directory path as the file destination.","solutions":["Point the destination at a file path that does not collide with an existing directory (dst + '/filename')","Delete or rename the conflicting directory on dstFS before copying","Catch PathIsDirectoryException and either fail with a clear message or route to a new destination","Use FileSystem.copyFromLocalFile(delSrc, overwrite, src, dst) when you want overwrite semantics instead of the hard-coded overwrite=false in this copy() overload"],"exampleFix":"// before\nFileUtil.copy(new File(\"data.txt\"), fs, new Path(\"/out/data.txt\"), false, conf);\n// throws PathIsDirectoryException when /out/data.txt is a directory\n\n// after\nPath dst = new Path(\"/out/data.txt\");\nFileStatus st = fs.exists(dst) ? fs.getFileStatus(dst) : null;\nif (st != null && st.isDirectory()) {\n  throw new IOException(\"Refusing to overwrite directory \" + dst);\n}\nFileUtil.copy(new File(\"data.txt\"), fs, dst, false, conf);","handlingStrategy":"validation","validationCode":"Path dst = new Path(\"/out/data.txt\");\nif (dstFS.exists(dst) && dstFS.getFileStatus(dst).isDirectory()) {\n  throw new IOException(\"Destination \" + dst + \" is a directory; refusing to copy file onto it\");\n}\nFileUtil.copy(src, dstFS, dst, false, conf);","typeGuard":null,"tryCatchPattern":"try {\n  FileUtil.copy(src, dstFS, dst, false, conf);\n} catch (PathIsDirectoryException e) {\n  // dst resolves to an existing directory; pick a file-level destination\n  dst = new Path(dst, src.getName());\n  FileUtil.copy(src, dstFS, dst, false, conf);\n}","preventionTips":["Always build file destinations as dstDir + '/' + fileName, never the bare directory","Before copy, assert !dstFS.exists(dst) || !dstFS.getFileStatus(dst).isDirectory()","Prefer copyFromLocalFile(delSrc, overwrite, ...) when overwrite semantics are wanted"],"tags":["path-is-directory","copy","destination-check","hdfs","fileutil"],"backgroundTag":"target-is-directory","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}