{"record":{"id":"1f0fbffe72752062","repo":"apache/hadoop","slug":"file-name-can-t-be-empty-string","errorCode":null,"errorMessage":"File name can't be empty string","messagePattern":"File name can't be empty string","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/GenericOptionsParser.java","lineNumber":432,"sourceCode":"   * So an input of  /home/user/file1,/home/user/file2 would return\n   * file:///home/user/file1,file:///home/user/file2.\n   *\n   * @param files the input files argument\n   * @param expandWildcard whether a wildcard entry is allowed and expanded. If\n   * true, any directory followed by a wildcard is a valid entry and is replaced\n   * with the list of jars in that directory. It is used to support the wildcard\n   * notation in a classpath.\n   * @return a comma-separated list of validated and qualified paths, or null\n   * if the input files argument is null\n   */\n  private String validateFiles(String files, boolean expandWildcard)\n      throws IOException {\n    if (files == null) {\n      return null;\n    }\n    String[] fileArr = files.split(\",\");\n    if (fileArr.length == 0) {\n      throw new IllegalArgumentException(\"File name can't be empty string\");\n    }\n    List<String> finalPaths = new ArrayList<>(fileArr.length);\n    for (int i =0; i < fileArr.length; i++) {\n      String tmp = fileArr[i];\n      if (tmp.isEmpty()) {\n        throw new IllegalArgumentException(\"File name can't be empty string\");\n      }\n      URI pathURI;\n      final String wildcard = \"*\";\n      boolean isWildcard = tmp.endsWith(wildcard) && expandWildcard;\n      try {\n        if (isWildcard) {\n          // strip the wildcard\n          tmp = tmp.substring(0, tmp.length() - 1);\n        }\n        // handle the case where a wildcard alone (\"*\") or the wildcard on the\n        // current directory (\"./*\") is specified\n        pathURI = matchesCurrentDirectory(tmp) ?","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/GenericOptionsParser.java#L414-L450","documentation":"GenericOptionsParser.validateFiles backs the -files/-libjars/-archives options: it splits the comma-separated argument and refuses empty names with IllegalArgumentException(\"File name can't be empty string\"). This first branch fires only when the split yields a zero-length array — effectively defensive dead code, because String.split never returns an empty array for a non-null string; the per-element check is the one normally hit. When launched via ServiceLauncher the IAE converts to exit code 40.","triggerScenarios":"Passing a degenerate empty value to -files/-libjars/-archives (e.g. an unset shell variable expanding to an empty string) — in practice caught by the sibling per-element check; this length==0 branch itself requires a split result of zero entries, which plain strings cannot produce.","commonSituations":"Oozie/shell workflows interpolating empty variables into -libjars; pipeline stages that conditionally build jar lists and pass the empty result anyway.","solutions":["Don't pass the option at all when the list is empty — guard the variable","Strip empty entries and trailing commas from the value before passing it","Log the fully assembled command line before executing to catch empty expansions"],"exampleFix":"# before\nhadoop jar job.jar -libjars \"$EXTRA_JARS\" Driver\n# after: omit the flag when the variable is empty\nEXTRA=()\n[ -n \"$EXTRA_JARS\" ] && EXTRA+=(-libjars \"$EXTRA_JARS\")\nhadoop jar job.jar \"${EXTRA[@]}\" Driver","handlingStrategy":"validation","validationCode":"String sanitize(String commaList) {\n  String joined = Arrays.stream(commaList.split(\",\"))\n      .map(String::trim).filter(s -> !s.isEmpty())\n      .collect(Collectors.joining(\",\"));\n  if (joined.isEmpty()) return null; // omit -libjars/-files entirely\n  return joined;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build CLI options conditionally: only pass -libjars/-files when the value is non-empty","Filter empty elements from comma lists before handing them to Hadoop","Echo the assembled command line in scripts to catch empty expansions"],"tags":["cli","generic-options-parser","libjars","files-option","validation"],"backgroundTag":"empty-path-argument","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}