apache/hadoop · error · IOException
Expected quoted string
Error message
Expected quoted string
What it means
Thrown by the MapReduce join expression parser (Parser.WNode.parse). After the comma that ends the InputFormat class name, the parser demands a double-quoted path token (TType.QUOT). This error means the next token exists but is not a double-quoted string — typically an unquoted path or a class name given where the path belongs.
Source
Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/join/Parser.java:319
if (TType.COMMA.equals(t.getType())) {
try {
inf = (InputFormat<?, ?>)ReflectionUtils.newInstance(
conf.getClassByName(sb.toString()), conf);
} catch (ClassNotFoundException e) {
throw new IOException(e);
} catch (IllegalArgumentException e) {
throw new IOException(e);
}
break;
}
sb.append(t.getStr());
}
if (!i.hasNext()) {
throw new IOException("Parse error");
}
Token t = i.next();
if (!TType.QUOT.equals(t.getType())) {
throw new IOException("Expected quoted string");
}
indir = t.getStr();
// no check for ll.isEmpty() to permit extension
}
private Configuration getConf(Configuration jconf) throws IOException {
Job job = Job.getInstance(jconf);
FileInputFormat.setInputPaths(job, indir);
return job.getConfiguration();
}
public List<InputSplit> getSplits(JobContext context)
throws IOException, InterruptedException {
return inf.getSplits(
new JobContextImpl(getConf(context.getConfiguration()),
context.getJobID()));
}
View on GitHub (pinned to 2add963021)
Solutions
- Wrap every tbl() path argument in literal double quotes: tbl(<InputFormat class>, "<path>")
- Escape embedded quotes correctly when the expression sits inside a Java string (\") or XML config (" or &#34; as needed)
- Use CompositeInputFormat.compose(...) which generates correctly quoted tbl(...) fragments
- Unit-test the expression with Parser.parse(expr, conf) before job submission
Example fix
// before
String expr = "inner(tbl(TextInputFormat, /data/a), tbl(TextInputFormat, /data/b))";
// after
String expr = "inner(tbl(org.apache.hadoop.mapreduce.lib.input.TextInputFormat, \"/data/a\"),"
+ "tbl(org.apache.hadoop.mapreduce.lib.input.TextInputFormat, \"/data/b\"))"; Defensive patterns
Strategy: validation
Validate before calling
static void requireQuotedPaths(String expr) {
// any tbl( whose second argument is not a double-quoted string
java.util.regex.Matcher m = java.util.regex.Pattern.compile(
"tbl\\([^,]+,\\s*([^\\\"])[^,]*\\)").matcher(expr);
if (m.find()) throw new IllegalArgumentException(
"tbl() path argument must be double-quoted: near '" + m.group(1) + "'");
} Try / catch
try { Parser.parse(expr, conf); } catch (IOException e) { throw new IllegalArgumentException("Bad join expression (check quoting): " + expr, e); } Prevention
- Always double-quote tbl() paths; single quotes are not recognized by the lexer
- Escape \" correctly when the expression is embedded in Java/XML
- Use compose() helpers which emit valid quoted fragments
When it happens
Trigger: The token following the COMMA in a tbl(...) node fails TType.QUOT.equals(t.getType()) at Parser.java:318. Examples: tbl(TextInputFormat, /data/a) — path not in double quotes; single quotes 'path' (the Lexer only designates '"' via tok.quoteChar('"')); tbl(fmt, tbl(...)) — nested node where a string was expected.
Common situations: Hand-writing mapreduce.join.expr and forgetting Java-style double quotes; using single quotes because the expression is embedded in another string; paths containing characters that break StreamTokenizer quoting; template code that interpolates a Path object without adding quotes.
Related errors
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/7f41baa964b3362d.
Report an issue: GitHub.