apache/hadoop · error · IOException

Expected strtype

Error message

Expected strtype

What it means

Only StrToken, lexed from identifiers and double-quoted strings, supports getStr(); Token.getStr() throws IOException("Expected strtype") otherwise. The main internal caller is WNode.parse, which concatenates string tokens before the comma into the InputFormat class name, so a numeric token in the class-name position (a name starting with a digit, or a number typed where the class goes) throws this. Custom Node subclasses calling getStr() on a non-IDENT/QUOT token hit the same guard.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/join/Parser.java:94

  @InterfaceAudience.Public
  @InterfaceStability.Evolving
  public static class Token {

    private TType type;

    Token(TType type) {
      this.type = type;
    }

    public TType getType() { return type; }
    public Node getNode() throws IOException {
      throw new IOException("Expected nodetype");
    }
    public double getNum() throws IOException {
      throw new IOException("Expected numtype");
    }
    public String getStr() throws IOException {
      throw new IOException("Expected strtype");
    }
  }

  @InterfaceAudience.Public
  @InterfaceStability.Evolving
  public static class NumToken extends Token {
    private double num;
    public NumToken(double num) {
      super(TType.NUM);
      this.num = num;
    }
    public double getNum() { return num; }
  }

  @InterfaceAudience.Public
  @InterfaceStability.Evolving
  public static class NodeToken extends Token {
    private Node node;

View on GitHub (pinned to 2add963021)

Solutions

  1. Give the fully-qualified InputFormat class name in letters (dots inside it lex fine as one IDENT), then a comma, then a double-quoted path
  2. Generate the expression with CompositeInputFormat.compose() so tbl(...) clauses are always well-formed
  3. In custom nodes, test for TType.IDENT or TType.QUOT before calling getStr()

Example fix

// before
job.set("mapred.join.expr", "inner(tbl(123,/data),tbl(F,/data2))");

// after
job.set("mapred.join.expr",
    CompositeInputFormat.compose("inner", SequenceFileInputFormat.class, "/data", "/data2"));
Defensive patterns

Strategy: type-guard

Validate before calling

// in a custom Node.parse, before reading a string formal
if (!(t instanceof Parser.StrToken)
    && !(Parser.TType.IDENT.equals(t.getType()) || Parser.TType.QUOT.equals(t.getType()))) {
  throw new IOException("string argument expected, got " + t.getType());
}

Type guard

boolean isStrToken(Parser.Token t) {
  return t instanceof Parser.StrToken; // covers IDENT and QUOT tokens
}

Try / catch

try {
  new CompositeInputFormat<Object>().setFormat(job);
} catch (IOException e) {
  throw new IllegalArgumentException("join expression has a non-string token where a class name or path was expected", e);
}

Prevention

When it happens

Trigger: tbl(123,"/path") or tbl(2MyFormat,"/path"): the leading number lexes as a NumToken and WNode.parse's sb.append(t.getStr()) throws; extension nodes reading a string formal that was given as a number or bare parenthesis.

Common situations: Hand-typed join expressions with numeric garbage before the comma; class names that begin with a digit; custom node formals drifting from the expression content.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/82a1cf8fe56764d1. Report an issue: GitHub.