apache/beam · error · IllegalArgumentException
Cannot infer types from
Error message
Cannot infer types from %s. This is currently unsupported, use List instead of Array.
What it means
CalciteUtils.sqlTypeWithAutoCast infers a Calcite RelDataType from a Java reflection Type for UDF/UDAF argument resolution. Java GenericArrayType (i.e. T[] parameters) is not supported, so IllegalArgumentException tells you to use java.util.List instead of raw arrays. Beam SQL maps List<E> to ARRAY and Map<K,V> to MAP, but not array-typed signatures.
Solutions
- Change the UDF signature to use java.util.List (e.g. List<String>) instead of String[].
- Wrap array values into a List before returning them from the UDF.
- Adjust the SQL call site to pass ARRAY literals, which map to List on the Java side.
Example fix
// before
public String[] splitNames(String input) { ... }
// after
public List<String> splitNames(String input) { ... } Defensive patterns
Strategy: type-guard
Validate before calling
for (Type p : method.getGenericParameterTypes()) {
if (p instanceof GenericArrayType) throw new IllegalArgumentException("Use List instead of arrays in UDF signature");
} Type guard
boolean usesArrays(Type t) { return t instanceof GenericArrayType || (t instanceof Class<?> c && c.isArray()); } Try / catch
try { relType = CalciteUtils.sqlTypeWithAutoCast(typeFactory, type); }
catch (IllegalArgumentException e) { /* reject UDF or rewrite signature before registration */ } Prevention
- Always use java.util.List in Beam SQL UDF signatures
- Add a startup check that rejects array-typed UDF methods
- Document List/Map conventions for UDF authors
- Validate UDF signatures at registration, not query time
When it happens
Trigger: Declaring a UDF method with an array parameter or return type (e.g. String[] or int[]) and invoking it through Beam SQL; the reflection-based type inference hits the `instanceof GenericArrayType` branch.
Common situations: Migrating plain Java UDFs that use arrays into Beam SQL UDFs; copying scalar UDF code from other SQL engines that allow array parameters.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Cannot create UDF from method: method
- Method is not public.
- must not throw checked exception
- No method annotated with @
- Cannot find a matching Beam FieldType for Calcite type:
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/6cc7bbb76bd32c52.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/utils/CalciteUtils.java:420
if (type instanceof Class && AbstractInstant.class.isAssignableFrom((Class<?>) type)) {
return typeFactory.createJavaType(Date.class);
} else if (type instanceof Class && ByteString.class.isAssignableFrom((Class<?>) type)) {
return typeFactory.createJavaType(byte[].class);
} else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (java.util.List.class.isAssignableFrom((Class<?>) parameterizedType.getRawType())) {
RelDataType elementType =
sqlTypeWithAutoCast(typeFactory, parameterizedType.getActualTypeArguments()[0]);
return typeFactory.createArrayType(elementType, UNLIMITED_ARRAY_SIZE);
} else if (java.util.Map.class.isAssignableFrom((Class<?>) parameterizedType.getRawType())) {
RelDataType mapElementKeyType =
sqlTypeWithAutoCast(typeFactory, parameterizedType.getActualTypeArguments()[0]);
RelDataType mapElementValueType =
sqlTypeWithAutoCast(typeFactory, parameterizedType.getActualTypeArguments()[1]);
return typeFactory.createMapType(mapElementKeyType, mapElementValueType);
}
} else if (type instanceof GenericArrayType) {
throw new IllegalArgumentException(
"Cannot infer types from "
+ type
+ ". This is currently unsupported, use List instead "
+ "of Array.");
}
if (type instanceof Class) {
Class<?> clazz = (Class<?>) type;
SqlTypeName sqlTypeName = JAVA_TO_SQL_TYPE_MAPPING.get(clazz);
if (sqlTypeName != null) {
return typeFactory.createTypeWithNullability(
typeFactory.createSqlType(sqlTypeName), !clazz.isPrimitive());
}
}
return typeFactory.createJavaType((Class) type);
}
}
View on GitHub (pinned to 12126d8942)