{"record":{"id":"ef18a6ba870a28d3","repo":"apache/hadoop","slug":"both-source-file-listing-and-source-paths-present","errorCode":null,"errorMessage":"Both source file listing and source paths present","messagePattern":"Both source file listing and source paths present","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-distcp/src/main/java/org/apache/hadoop/tools/OptionsParser.java","lineNumber":275,"sourceCode":"    String[] leftOverArgs = command.getArgs();\n    if (leftOverArgs == null || leftOverArgs.length < 1) {\n      throw new IllegalArgumentException(\"Target path not specified\");\n    }\n\n    //Last Argument is the target path\n    targetPath = new Path(leftOverArgs[leftOverArgs.length - 1].trim());\n\n    //Copy any source paths in the arguments to the list\n    for (int index = 0; index < leftOverArgs.length - 1; index++) {\n      sourcePaths.add(new Path(leftOverArgs[index].trim()));\n    }\n\n    /* If command has source file listing, use it else, fall back on source\n       paths in args.  If both are present, throw exception and bail */\n    if (command.hasOption(\n        DistCpOptionSwitch.SOURCE_FILE_LISTING.getSwitch())) {\n      if (!sourcePaths.isEmpty()) {\n        throw new IllegalArgumentException(\"Both source file listing and \" +\n            \"source paths present\");\n      }\n      return new DistCpOptions.Builder(new Path(getVal(command,\n          DistCpOptionSwitch.SOURCE_FILE_LISTING.getSwitch())), targetPath);\n    } else {\n      if (sourcePaths.isEmpty()) {\n        throw new IllegalArgumentException(\"Neither source file listing nor \" +\n            \"source paths present\");\n      }\n      return new DistCpOptions.Builder(sourcePaths, targetPath);\n    }\n  }\n\n  private static String getVal(CommandLine command, String swtch) {\n    if (swtch == null) {\n      return null;\n    }\n    String optionValue = command.getOptionValue(swtch.trim());","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-distcp/src/main/java/org/apache/hadoop/tools/OptionsParser.java#L257-L293","documentation":"Sources can be specified two ways: a -f file listing, or positional source paths in front of the target. parseSourceAndTargetPaths found both present - -f was given AND at least one extra positional path besides the target - and refuses to guess which set to copy.","triggerScenarios":"hadoop distcp -f /tmp/list.txt hdfs://nn/src hdfs://nn/tgt - two positional paths means hdfs://nn/src became a source path while -f also supplied a listing.","commonSituations":"incrementally editing a working one-liner by adding -f but forgetting to remove the inline source; scripts appending a default source path unconditionally; operators assuming -f is an additional filter rather than an alternative.","solutions":["Pick one source mechanism: remove -f and keep inline paths, or keep -f and remove all inline sources so only the target remains.","Re-run: hadoop distcp -f /tmp/list.txt hdfs://nn/tgt or hadoop distcp hdfs://nn/src hdfs://nn/tgt.","Audit wrapper scripts for unconditional source-path appends."],"exampleFix":"# before: both -f and an inline source (plus target)\nhadoop distcp -f /tmp/list.txt hdfs://nn/src hdfs://nn/tgt\n\n# after: sources from exactly one place\nhadoop distcp -f /tmp/list.txt hdfs://nn/tgt","handlingStrategy":"validation","validationCode":"// Wrapper validation: -f and inline source paths are mutually exclusive\nboolean hasF = false;\nList<String> positional = new ArrayList<>();\nfor (int i = 0; i < args.length; i++) {\n  if (\"-f\".equals(args[i])) { hasF = true; i++; } // skip its value\n  else if (!args[i].startsWith(\"-\")) positional.add(args[i]);\n}\nif (hasF && positional.size() > 1) {\n  throw new IllegalArgumentException(\n      \"-f given plus inline sources \" + positional.subList(0, positional.size() - 1));\n}","typeGuard":null,"tryCatchPattern":"try {\n  OptionsParser.parse(args);\n} catch (IllegalArgumentException e) {\n  if (\"Both source file listing and source paths present\".equals(e.getMessage())) {\n    // drop either -f or the inline sources, then re-run\n    throw new IllegalArgumentException(\"Pick one source mechanism: -f OR inline paths\", e);\n  }\n  throw e;\n}","preventionTips":["Treat -f as a replacement for inline sources, never an addition.","When editing working commands, remove the superseded source form."],"tags":["distcp","cli","conflicting-options","source-paths"],"backgroundTag":"conflicting-cli-options","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}