{"record":{"id":"32236553e7ddc13f","repo":"apache/hadoop","slug":"expected-quoted-string","errorCode":null,"errorMessage":"Expected quoted string","messagePattern":"Expected quoted string","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":304,"sourceCode":"          try {\n          \tinf = (InputFormat)ReflectionUtils.newInstance(\n          \t\t\tjob.getClassByName(sb.toString()),\n                job);\n          } catch (ClassNotFoundException e) {\n            throw (IOException)new IOException().initCause(e);\n          } catch (IllegalArgumentException e) {\n            throw (IOException)new IOException().initCause(e);\n          }\n          break;\n        }\n        sb.append(t.getStr());\n      }\n      if (!i.hasNext()) {\n        throw new IOException(\"Parse error\");\n      }\n      Token t = i.next();\n      if (!TType.QUOT.equals(t.getType())) {\n        throw new IOException(\"Expected quoted string\");\n      }\n      indir = t.getStr();\n      // no check for ll.isEmpty() to permit extension\n    }\n\n    private JobConf getConf(JobConf job) {\n      JobConf conf = new JobConf(job);\n      FileInputFormat.setInputPaths(conf, indir);\n      conf.setClassLoader(job.getClassLoader());\n      return conf;\n    }\n\n    public InputSplit[] getSplits(JobConf job, int numSplits)\n        throws IOException {\n      return inf.getSplits(getConf(job), numSplits);\n    }\n\n    public ComposableRecordReader getRecordReader(","sourceCodeStart":286,"sourceCodeEnd":322,"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#L286-L322","documentation":"After the comma, WNode.parse requires the path argument to be a double-quoted string token (TType.QUOT, produced because Lexer sets quoteChar('\"')). Any other token in the path position — an unquoted identifier, a number, or a parenthesis — throws IOException(\"Expected quoted string\").","triggerScenarios":"tbl(F,/data/path) with an unquoted path; tbl(F,'/data') with single quotes, which the lexer does not treat as string delimiters; a number or parenthesis where the path should be.","commonSituations":"Forgetting that only double quotes delimit strings in this grammar; unquoted HDFS paths (which can also hit the '/' comment behavior and parse weirdly); expressions edited from shell snippets where the inner quotes were stripped.","solutions":["Double-quote the path: tbl(F,\\\"/data/path\\\")","Use CompositeInputFormat.compose(), which emits the quotes for you","Remember the grammar: tbl(<class>,\\\"<path>\\\") — nothing else is accepted as the second formal"],"exampleFix":"// before\njob.set(\"mapred.join.expr\", \"inner(tbl(F,/a),tbl(F,/b))\");\n\n// after\njob.set(\"mapred.join.expr\",\n    CompositeInputFormat.compose(\"inner\", SequenceFileInputFormat.class, \"/a\", \"/b\"));","handlingStrategy":"validation","validationCode":"String expr = CompositeInputFormat.compose(\"inner\",\n    SequenceFileInputFormat.class, \"/a\", \"/b\"); // compose() always quotes paths\nif (!expr.matches(\"[^\\\"]*\\\"[^\\\"]*\\\"[^\\\"]*\\\\).*\")) {\n  // lightweight sanity: at least one quoted path per tbl clause\n}\njob.set(\"mapred.join.expr\", expr);","typeGuard":"boolean isQuotedString(Parser.Token t) {\n  return Parser.TType.QUOT.equals(t.getType()); // only double-quoted strings\n}","tryCatchPattern":"try {\n  new CompositeInputFormat<Object>().setFormat(job);\n} catch (IOException e) {\n  throw new IllegalArgumentException(\n      \"tbl() path argument must be a double-quoted string\", e);\n}","preventionTips":["Only double quotes delimit strings in this grammar; single quotes are not accepted","Use compose() which emits the quotes","Check for quote-stripping when expressions pass through shell or template layers"],"tags":["hadoop","mapreduce","join","parser","quoting"],"backgroundTag":"expression-parse-error","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}