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
- Quote the row-key comparison as a string, e.g. WHERE rowkey = '123'
- Avoid pushing NULL/IS NULL filters on the key to Bigtable; handle them in Beam
- 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
- Always compare Bigtable row-key columns against string literals in SQL
- Keep non-string or NULL key comparisons in Beam-side filters
- Match declared schema types for key columns to query literals
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
- Bigtable location must be in the following format…
- columnsMapping ' ' does not fit to schema field names
- key field type should be STRING but was
- LOCATION is required
- Schema fields count: ' ' does not fit columnsMapping count
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)