apache/beam · error · IllegalArgumentException

Expected non-null String literal

Error message

Expected non-null String literal

What it means

BigtableFilter.translateRexNodeToRowFilter converts a pushed-down equality filter on the row key into a Bigtable RowFilter regex. The literal operand must be a Java String; if RexLiteral.getValueAs(String.class) returns null (literal is not a string type) it throws IllegalArgumentException because a non-string key comparison cannot be translated to a row-key regex.

Solutions

  1. Quote the row-key comparison as a string, e.g. WHERE rowkey = '123'
  2. Avoid pushing NULL/IS NULL filters on the key to Bigtable; handle them in Beam
  3. Cast the literal to the key's declared string type in the query before filtering

Example fix

// before
SELECT * FROM bigtable_t WHERE rowkey = 123
// after
SELECT * FROM bigtable_t WHERE rowkey = '123'
Defensive patterns

Strategy: type-guard

Validate before calling

// before pushdown
RexLiteral lit = literals.get(0);
String s = lit.getValueAs(String.class);
if (s == null) throw new IllegalArgumentException("row-key filter literal must be a string");

Type guard

boolean isStringLiteral(RexLiteral l) {
  return l != null && l.getType().getSqlTypeName() == SqlTypeName.VARCHAR && l.getValueAs(String.class) != null;
}

Try / catch

try {
  RowFilter rf = bigtableFilter.getFilters(...);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Expected non-null String literal")) { /* evaluate filter locally instead */ }
  throw e;
}

Prevention

When it happens

Trigger: Applying a WHERE clause against a Bigtable row-key column with a non-string literal (e.g. rowkey = 123) or with a NULL literal, then calling getFilters → translateRexNodeToRowFilter; literals.get(0).getValueAs(String.class) yields null.

Common situations: Comparing the row key to numeric or binary literals; passing NULL comparisons expecting pushdown; column-type mismatches between the schema declaration and query literals.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/29875bdea0891413. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/bigtable/BigtableFilter.java:97

        String.format("Only one LIKE operation is allowed. Got %s operations", supported.size()));
    return translateRexNodeToRowFilter(supported.get(0));
  }

  private RowFilter translateRexNodeToRowFilter(RexNode node) {
    checkNodeIsCoposite(node);
    checkArgument(LIKE.equals(node.getKind()), "Only LIKE operation is supported.");

    List<RexLiteral> literals = filterOperands((RexCall) node, RexLiteral.class);
    List<RexInputRef> inputRefs = filterOperands((RexCall) node, RexInputRef.class);

    checkArgument(literals.size() == 1);
    checkArgument(inputRefs.size() == 1);

    checkFieldIsKey(inputRefs.get(0));
    String literal = literals.get(0).getValueAs(String.class);

    if (literal == null) {
      throw new IllegalArgumentException("Expected non-null String literal");
    }

    return RowFilter.newBuilder().setRowKeyRegexFilter(byteStringUtf8(literal)).build();
  }

  private void checkFieldIsKey(RexInputRef inputRef) {
    String inputFieldName = schema.getField(inputRef.getIndex()).getName();
    checkArgument(
        KEY.equals(inputFieldName),
        "Only 'key' queries are supported. Got field " + inputFieldName);
  }

  private static boolean isSupported(RexNode node) {
    checkNodeIsCoposite(node);
    if (!LIKE.equals(node.getKind())) {
      return false;
    }

View on GitHub (pinned to 12126d8942)