{"record":{"id":"b2e0561bc819440e","repo":"apache/hadoop","slug":"unexpected-type","errorCode":null,"errorMessage":"Unexpected: \" + type","messagePattern":"Unexpected: \" \\+ type","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/join/Parser.java","lineNumber":176,"sourceCode":"        case StreamTokenizer.TT_EOF:\n        case StreamTokenizer.TT_EOL:\n          return null;\n        case StreamTokenizer.TT_NUMBER:\n          return new NumToken(tok.nval);\n        case StreamTokenizer.TT_WORD:\n          return new StrToken(TType.IDENT, tok.sval);\n        case '\"':\n          return new StrToken(TType.QUOT, tok.sval);\n        default:\n          switch (type) {\n            case ',':\n              return new Token(TType.COMMA);\n            case '(':\n              return new Token(TType.LPAREN);\n            case ')':\n              return new Token(TType.RPAREN);\n            default:\n              throw new IOException(\"Unexpected: \" + type);\n          }\n      }\n    }\n  }\n\n  @InterfaceAudience.Public\n  @InterfaceStability.Evolving\n  public abstract static class Node implements ComposableInputFormat {\n    /**\n     * Return the node type registered for the particular identifier.\n     * By default, this is a CNode for any composite node and a WNode\n     * for &quot;wrapped&quot; nodes. User nodes will likely be composite\n     * nodes.\n     * @see #addIdentifier(java.lang.String, java.lang.Class[], java.lang.Class, java.lang.Class)\n     * @see CompositeInputFormat#setFormat(org.apache.hadoop.mapred.JobConf)\n     */\n    static Node forIdent(String ident) throws IOException {\n      try {","sourceCodeStart":158,"sourceCodeEnd":194,"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/join/Parser.java#L158-L194","documentation":"The join-expression lexer (Parser.Lexer over java.io.StreamTokenizer) accepts identifiers (letters, digits, '_', '$', and '.' inside words), numbers, double-quoted strings, commas, and parentheses. Lexer.next() throws IOException(\"Unexpected: <char code>\") for any other character, where the number is the character code (e.g. 58 for ':'). Note that an unquoted '/' does not throw: StreamTokenizer treats it as a comment character and silently swallows the rest of the line.","triggerScenarios":"Unquoted characters outside the grammar in mapred.join.expr: an unquoted URI tbl(Fmt,hdfs://nn/data) hits ':'; property-style syntax inner(a=b); a single-quoted path 'x'; stray brackets or semicolons from shell editing.","commonSituations":"Pasting HDFS URIs or globs into the expression without double quotes; hand-editing the expression in job config XML and introducing stray characters; quotes stripped by shell one-liners.","solutions":["Wrap every path in double quotes: tbl(<class>,\\\"hdfs://nn/data\\\")","Let CompositeInputFormat.compose() generate and quote paths for you","Keep the expression to identifiers, numbers, commas, parens, and double-quoted strings only"],"exampleFix":"// before: unquoted URI — ':' is not in the lexer grammar\njob.set(\"mapred.join.expr\", \"inner(tbl(F,hdfs://nn/a),tbl(F,hdfs://nn/b))\");\n\n// after: paths double-quoted (compose() does this for you)\njob.set(\"mapred.join.expr\",\n    CompositeInputFormat.compose(\"inner\", SequenceFileInputFormat.class,\n        \"hdfs://nn/a\", \"hdfs://nn/b\"));","handlingStrategy":"validation","validationCode":"String expr = CompositeInputFormat.compose(\"inner\",\n    SequenceFileInputFormat.class, \"hdfs://nn/a\", \"hdfs://nn/b\");\njob.set(\"mapred.join.expr\", expr);\ntry {\n  new CompositeInputFormat<Text>().setFormat(job); // lexes + parses client-side\n} catch (IOException e) {\n  throw new IllegalArgumentException(\"join expression contains a character outside the grammar\", e);\n}","typeGuard":null,"tryCatchPattern":"try {\n  new CompositeInputFormat<Object>().setFormat(job);\n} catch (IOException e) {\n  throw new IllegalArgumentException(\n      \"unexpected character in mapred.join.expr; quote all paths and URIs\", e);\n}","preventionTips":["Double-quote every path and URI in the expression","Restrict expressions to identifiers, numbers, commas, parens, and double-quoted strings","Remember an unquoted '/' acts as a comment start and silently truncates the expression"],"tags":["hadoop","mapreduce","join","lexer","parser","expression"],"backgroundTag":"expression-parse-error","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}