{"record":{"id":"31bea43e7d71cde0","repo":"apache/hadoop","slug":"name-cannot-be-have-a-char","errorCode":null,"errorMessage":"Name cannot be have a '{}' char","messagePattern":"Name cannot be have a '(.+?)' char","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/lib/MultipleOutputs.java","lineNumber":205,"sourceCode":"   * @param namedOutput named output Name\n   * @throws IllegalArgumentException if the output name is not valid.\n   */\n  private static void checkTokenName(String namedOutput) {\n    if (namedOutput == null || namedOutput.length() == 0) {\n      throw new IllegalArgumentException(\n        \"Name cannot be NULL or emtpy\");\n    }\n    for (char ch : namedOutput.toCharArray()) {\n      if ((ch >= 'A') && (ch <= 'Z')) {\n        continue;\n      }\n      if ((ch >= 'a') && (ch <= 'z')) {\n        continue;\n      }\n      if ((ch >= '0') && (ch <= '9')) {\n        continue;\n      }\n      throw new IllegalArgumentException(\n        \"Name cannot be have a '\" + ch + \"' char\");\n    }\n  }\n\n  /**\n   * Checks if a named output name is valid.\n   *\n   * @param namedOutput named output Name\n   * @throws IllegalArgumentException if the output name is not valid.\n   */\n  private static void checkNamedOutputName(String namedOutput) {\n    checkTokenName(namedOutput);\n    // name cannot be the name used for the default output\n    if (namedOutput.equals(\"part\")) {\n      throw new IllegalArgumentException(\n        \"Named output name cannot be 'part'\");\n    }\n  }","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/lib/MultipleOutputs.java#L187-L223","documentation":"checkTokenName() in MultipleOutputs accepts only the characters A-Z, a-z and 0-9 in a named output (and in a multi name); every other character triggers this IllegalArgumentException (the message grammar is original: \"Name cannot be have a ...\"). Notably underscore, dash and dot are NOT allowed in this mapred-era validator. The check runs for addNamedOutput/addMultiNamedOutput and for the multiName of getCollector on multi outputs.","triggerScenarios":"addNamedOutput(conf, \"click-stream\", ...), \"out_1\", \"cat.ext\" or any name containing '-', '_', '.', '/' or whitespace. Also mos.getCollector(\"seq\", \"2024-01\", reporter) — the dash in the date fails the check even though the named output itself was registered fine.","commonSituations":"Natural naming from file names, dates or categories ('click_stream', '2024-01') that includes separators; ports of the new-API org.apache.hadoop.mapreduce.lib.output.MultipleOutputs code where names with '_' and '-' were tolerated, then hitting the stricter old-API validator.","solutions":["Restrict names to letters and digits only: camelCase or simple concatenation ('clickstream', '202401')","Sanitize computed names before use: name.replaceAll(\"[^A-Za-z0-9]\", \"\")","Centralize naming in one helper used by both driver and task so both sides apply the same sanitization"],"exampleFix":"// before: '-' is rejected by checkTokenName\nMultipleOutputs.addNamedOutput(conf, \"click-stream\", TextOutputFormat.class, Text.class, Text.class);\n\n// after: alphanumeric-only name\nMultipleOutputs.addNamedOutput(conf, \"clickstream\", TextOutputFormat.class, Text.class, Text.class);","handlingStrategy":"validation","validationCode":"static String sanitizeToken(String s) {\n  String t = (s == null) ? \"\" : s.replaceAll(\"[^A-Za-z0-9]\", \"\");\n  return t.isEmpty() ? \"NA\" : t;\n}\n// use everywhere a named output / multi name is built\nMultipleOutputs.addNamedOutput(conf, sanitizeToken(channel), fmt, k, v);","typeGuard":"static boolean isAlphanumericToken(String name) {\n  return name != null && name.matches(\"[A-Za-z0-9]+\");\n}","tryCatchPattern":null,"preventionTips":["Remember the old-API validator allows ONLY [A-Za-z0-9] — no '_', '-', '.' or '/'","Run generated names through a single sanitizer before addNamedOutput/getCollector","Add a unit test that registers and collects with your real production name set"],"tags":["hadoop","mapreduce","multiple-outputs","validation","naming"],"backgroundTag":"invalid-identifier-characters","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}