{"record":{"id":"dabbc1733fe99495","repo":"apache/hadoop","slug":"is-a-directory-dabbc1","errorCode":null,"errorMessage":"Is a directory","messagePattern":"Is a directory","errorType":"exception","errorClass":"PathIsDirectoryException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/CopyCommands.java","lineNumber":83,"sourceCode":"\n    protected PathData dst = null;\n    protected String delimiter = null;\n    private boolean skipEmptyFileDelimiter;\n    protected List<PathData> srcs = null;\n\n    @Override\n    protected void processOptions(LinkedList<String> args) throws IOException {\n      try {\n        CommandFormat cf = new CommandFormat(2, Integer.MAX_VALUE, \"nl\",\n            \"skip-empty-file\");\n        cf.parse(args);\n\n        delimiter = cf.getOpt(\"nl\") ? \"\\n\" : null;\n        skipEmptyFileDelimiter = cf.getOpt(\"skip-empty-file\");\n\n        dst = new PathData(new URI(args.removeLast()), getConf());\n        if (dst.exists && dst.stat.isDirectory()) {\n          throw new PathIsDirectoryException(dst.toString());\n        }\n        srcs = new LinkedList<PathData>();\n      } catch (URISyntaxException e) {\n        throw new IOException(\"unexpected URISyntaxException\", e);\n      }\n    }\n\n    @Override\n    protected void processArguments(LinkedList<PathData> items)\n    throws IOException {\n      super.processArguments(items);\n      if (exitCode != 0) { // check for error collecting paths\n        return;\n      }\n      FSDataOutputStream out = dst.fs.create(dst.path);\n      try {\n        for (PathData src : srcs) {\n          if (src.stat.getLen() != 0) {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/CopyCommands.java#L65-L101","documentation":"PathIsDirectoryException (message 'Is a directory') thrown by Getmerge.processOptions (CopyCommands.java:83) for the 'hadoop fs -getmerge' command. The destination argument (the last argument) already exists and is a directory. getmerge merges many source files into ONE local output file, so the destination must be a (typically nonexistent) file path, not a directory.","triggerScenarios":"'hadoop fs -getmerge /hdfs/src/dir /local/output' where /local/output is an existing directory; scripts that pass a target directory expecting cp/mv-like semantics; a destination created beforehand with mkdir by the same script.","commonSituations":"Copy/paste of a 'cp -r' idiom where the last arg is a directory; automation that derives the destination from a directory variable; users expecting getmerge to write merged.txt into the given folder automatically.","solutions":["Point the destination at a file name that does not exist: 'hadoop fs -getmerge /hdfs/src/dir /local/merged.txt'","Or keep the directory and append a file name to it: 'hadoop fs -getmerge /hdfs/src/dir /local/output/merged.txt'","If the directory was created by mistake in a prior step, remove or skip that mkdir","Use the -nl option only after the destination is a valid file path (options are unrelated but often appear in the same failing scripts)"],"exampleFix":"# before\nmkdir -p /local/out\nhadoop fs -getmerge /src/dir /local/out      # Is a directory\n\n# after\nmkdir -p /local/out\nhadoop fs -getmerge /src/dir /local/out/merged.txt","handlingStrategy":"validation","validationCode":"PathData dst = new PathData(new URI(dstArg), getConf());\nif (dst.exists && dst.stat.isDirectory()) {\n  throw new PathIsDirectoryException(dst.toString());\n}","typeGuard":"static boolean isValidGetmergeDestination(PathData dst) throws IOException {\n  return !(dst.exists && dst.stat.isDirectory());\n}","tryCatchPattern":"try {\n  // run getmerge\n} catch (PathIsDirectoryException e) {\n  // append an output file name to the directory and retry\n}","preventionTips":["Always pass a full output FILE path to getmerge, never a directory","In scripts, derive the destination as \"$DIR/merged.txt\"","Never mkdir the getmerge destination beforehand"],"tags":["hadoop","getmerge","shell","path-is-directory","argument-validation"],"backgroundTag":"path-is-directory","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}