apache/beam · error · IllegalArgumentException
Unknown type of fn class %s
Error message
Unknown type of fn class %s
What it means
FlatMapElements.via(fn) accepts only a few fn shapes: a function/SerializableFunction, or (in the failing expand) a specific class type it knows how to adapt into a DoFn. When the fn object is of any other class, expand throws this IllegalArgumentException.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/FlatMapElements.java:174
.getRequirements()
.getSideInputs()));
} else if (fn instanceof ProcessFunction) {
return input.apply(
"FlatMap",
ParDo.of(
new FlatMapDoFn() {
@ProcessElement
public void processElement(
@Element InputT element, OutputReceiver<OutputT> receiver) throws Exception {
Iterable<OutputT> res =
((ProcessFunction<InputT, Iterable<OutputT>>) fn).apply(element);
for (OutputT output : res) {
receiver.output(output);
}
}
}));
} else {
throw new IllegalArgumentException(
String.format("Unknown type of fn class %s", fn.getClass()));
}
}
private abstract class FlatMapDoFn extends DoFn<InputT, OutputT> {
@Override
public TypeDescriptor<InputT> getInputTypeDescriptor() {
return inputType;
}
@Override
public TypeDescriptor<OutputT> getOutputTypeDescriptor() {
checkState(
outputType != null,
"%s output type descriptor was null; "
+ "this probably means that getOutputTypeDescriptor() was called after "
+ "serialization/deserialization, but it is only available prior to "View on GitHub (pinned to 12126d8942)
Solutions
- Pass a lambda or method reference typed as ProcessFunction<InputT, Iterable<OutputT>>
- Ensure the generic type parameters of FlatMapElements.via(...) match the fn's input/output types
- If using a class, implement SerializableFunction<InputT, Iterable<OutputT>> (or the required interface) directly
Example fix
// before
FlatMapElements.via(new MyWeirdFn());
// after
FlatMapElements.via((ProcessFunction<String, Iterable<Integer>>) s -> Arrays.asList(s.split(" "))) Defensive patterns
Strategy: type-guard
Validate before calling
// Verify the fn type before passing to FlatMapElements
if (!(fn instanceof ProcessFunction) && !(fn instanceof SerializableFunction)) {
throw new IllegalArgumentException("fn must be a ProcessFunction/SerializableFunction");
} Type guard
boolean isValidFlatMapFn(Object fn) {
return fn instanceof ProcessFunction || fn instanceof SerializableFunction;
} Try / catch
try { pc.apply(FlatMapElements.into(td).via(fn)); }
catch (IllegalArgumentException e) { log.error("bad fn class", e); } Prevention
- Always pass lambdas or method references typed to ProcessFunction<InputT, Iterable<OutputT>>
- Check generic type parameters match the FlatMapElements.into() type descriptor
- Avoid raw types when declaring the fn variable
When it happens
Trigger: Calling FlatMapElements.via() with a fn whose runtime class is neither ProcessFunction/SerializableFunction nor one of the supported inner adapter classes (e.g. a class already carrying an output type not matching the expected type parameter).
Common situations: Type-erasure mistakes: passing a lambda assigned to a raw or wrong generic type; reusing a fn class from a different transform; calling via() with an anonymous class of unexpected shape.
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
- Cannot infer coder for type parameter
- is not a ParameterizedType
- Cannot encode elements of type %s with coder %s: the generic
- Cannot provide a coder for wildcard type %s.
- Cannot provide coder for parameterized type %s: %s
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/27a78f35c38a80f3.
Report an issue: GitHub.