apache/beam · error · UnsupportedOperationException
Analytics Function [ ] is not supported
Error message
Analytics Function [%s] is not supported
What it means
BeamBuiltinAnalyticFunctions.create(functionName, fieldType) looks up functionName in the BUILTIN_ANALYTIC_FACTORIES registry of supported analytic (window) function combiners. If the name is not registered (aggregatorFactory == null) it throws UnsupportedOperationException stating the analytic function is unsupported. This guards the closed set of built-in analytic functions Beam SQL can plan.
Solutions
- Check BUILTIN_ANALYTIC_FACTORIES in BeamBuiltinAnalyticFunctions for the exact supported function names and use one of those in the query.
- Upgrade the Beam version — newer releases add more analytic functions.
- Implement the window computation manually (e.g. with beam-sdks-java extensions or a custom CombineFn and windowing) and register it in the factory map if extending the SDK.
- Fix name casing/spelling — the registry lookup is exact-string.
Example fix
// before
CombineFn fn = BeamBuiltinAnalyticFunctions.create("NTILE", fieldType); // throws
// after
CombineFn fn = BeamBuiltinAnalyticFunctions.create("LAG", fieldType); // registered name
// or implement NTILE manually via GlobalWindows + custom combiner Defensive patterns
Strategy: validation
Validate before calling
java.util.Set<String> supported = java.util.Set.of("LAG", "LEAD", "FIRST_VALUE", "LAST_VALUE", "NTH_VALUE"); // mirror BUILTIN_ANALYTIC_FACTORIES keys
if (!supported.contains(functionName)) {
throw new IllegalArgumentException("Analytic function not supported: " + functionName);
} Type guard
boolean analyticSupported(String fn, org.apache.beam.sdk.extensions.sql.impl.transform.BeamBuiltinAnalyticFunctions ignored) {
// consult the registry directly if accessible
return fn != null && BUILTIN_ANALYTIC_FACTORIES.containsKey(fn);
} Try / catch
try {
Combine.CombineFn<?, ?, ?> fn = BeamBuiltinAnalyticFunctions.create(functionName, fieldType);
} catch (UnsupportedOperationException e) {
// fall back to manual window computation or a different supported function
} Prevention
- Check the supported analytic function list for your Beam version before writing OVER() queries.
- Match function names exactly — the registry lookup is case-sensitive string equality.
- On upgrade, re-check that newly used analytic functions are registered.
When it happens
Trigger: Calling BeamBuiltinAnalyticFunctions.create with a function name string that is not in the registry — e.g. an unsupported window function like NTILE or PERCENT_RANK in an OVER clause, or a misspelled function name passed programmatically.
Common situations: Using an analytic function available in other SQL engines (e.g. LISTAGG, MEDIAN as analytic) that Beam SQL has not implemented; case-sensitivity or spelling mismatch of the function name; version differences where a function was added only in newer Beam releases.
Related errors
- A 'datagen' table requires either 'rows-per-second' (for…
- Beam write property ' ' is not supported. Writing to Delta…
- Bigtable location must be in the following format…
- Cannot create UDF from method: method
- Cannot get type arguments for
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/5939c5d5ac5c7cc0.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/transform/BeamBuiltinAnalyticFunctions.java:56
// Aggregate Analytic Functions
.putAll(BeamBuiltinAggregations.BUILTIN_AGGREGATOR_FACTORIES)
// Navigation Functions
.put("FIRST_VALUE", typeName -> navigationFirstValue())
.put("LAST_VALUE", typeName -> navigationLastValue())
// Numbering Functions
.put("ROW_NUMBER", typeName -> numberingRowNumber())
.put("DENSE_RANK", typeName -> numberingDenseRank())
.put("RANK", typeName -> numberingRank())
.put("PERCENT_RANK", typeName -> numberingPercentRank())
.build();
public static Combine.CombineFn<?, ?, ?> create(String functionName, Schema.FieldType fieldType) {
Function<Schema.FieldType, Combine.CombineFn<?, ?, ?>> aggregatorFactory =
BUILTIN_ANALYTIC_FACTORIES.get(functionName);
if (aggregatorFactory != null) {
return aggregatorFactory.apply(fieldType);
}
throw new UnsupportedOperationException(
String.format("Analytics Function [%s] is not supported", functionName));
}
// Navigation functions
public static <T> Combine.CombineFn<T, ?, T> navigationFirstValue() {
return new FirstValueCombineFn();
}
public static <T> Combine.CombineFn<T, ?, T> navigationLastValue() {
return new LastValueCombineFn();
}
private static class FirstValueCombineFn<T> extends Combine.CombineFn<T, Optional<T>, T> {
private FirstValueCombineFn() {}
@Override
public Optional<T> createAccumulator() {
return Optional.empty();View on GitHub (pinned to 12126d8942)