apache/beam · error · UnsupportedOperationException
${config}
Error message
${config} What it means
JavaRowUdf selects how to build the UDF function: from an inline expression, a callable class, or a named function on a path. If none of expression, callable, or name is set in the config, createFunction has no creation strategy and throws UnsupportedOperationException with the config's toString as the message.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/transforms/providers/JavaRowUdf.java:193
Function.class,
new TypeDescriptors.TypeVariableExtractor<Function<InputT, OutputT>, OutputT>() {});
}
}
@SuppressWarnings({
"nullness" // TODO(https://github.com/apache/beam/issues/20497)
})
private static FunctionAndType createFunction(Configuration config, Schema inputSchema)
throws ReflectiveOperationException, StringCompiler.CompileException, MalformedURLException {
config.validate();
if (!Strings.isNullOrEmpty(config.getExpression())) {
return createFunctionFromExpression(config.getExpression(), inputSchema);
} else if (!Strings.isNullOrEmpty(config.getCallable())) {
return createFuctionFromCallable(config.getCallable());
} else if (!Strings.isNullOrEmpty(config.getName())) {
return createFunctionFromName(config.getName(), config.getPath());
} else {
throw new UnsupportedOperationException(config.toString());
}
}
private static FunctionAndType createFunctionFromExpression(String expression, Schema inputSchema)
throws StringCompiler.CompileException, ReflectiveOperationException {
if (inputSchema.hasField(expression)) {
final int ix = inputSchema.indexOf(expression);
return new FunctionAndType(
inputSchema.getField(expression).getType(), (Row row) -> row.getValue(ix));
} else {
Map<String, Type> fieldTypes = new HashMap<>();
for (Schema.Field field : inputSchema.getFields()) {
if (expression.indexOf(field.getName()) != -1) {
fieldTypes.put(field.getName(), typeFromFieldType(field.getType()));
}
}
Type type = StringCompiler.guessExpressionType(expression, fieldTypes);
StringBuilder source = new StringBuilder();View on GitHub (pinned to 12126d8942)
Solutions
- Set one of 'expression', 'callable', or 'name' in the UDF configuration
- Fix typos in config keys so the intended option is populated
- Validate the config object before passing it to the transform
Example fix
// before udf: language: sql # after udf: language: sql expression: "count * 2"
Defensive patterns
Strategy: validation
Validate before calling
if (Strings.isNullOrEmpty(config.getExpression())
&& Strings.isNullOrEmpty(config.getCallable())
&& Strings.isNullOrEmpty(config.getName()))
throw new IllegalArgumentException("UDF config requires expression, callable, or name"); Prevention
- Validate UDF YAML/JSON config keys at pipeline-construction time
- Use a schema-validated config loader to catch missing fields
When it happens
Trigger: createFunction called (via functionAndType) with a JavaRowUdf config where getExpression(), getCallable(), and getName() are all null or empty strings.
Common situations: Incomplete YAML/JSON config for the UDF transform; typo'd config keys so values land in the wrong fields; config built programmatically without setting any of the three options.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- No filesystem found for scheme
- Exploded field %s must be an iterable type, got %s.
- boolean cross product parameter required to explode more tha
- ${fieldType}
- Unknown log level ${level}. Valid log levels are ${validLeve
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/bddc0c45c8e74509.
Report an issue: GitHub.