apache/beam · error · IllegalStateException
Subclass of InferableFunction must override 'apply' method o
Error message
Subclass of InferableFunction must override 'apply' method or pass a ProcessFunction to the constructor, usually via a lambda or method reference.
What it means
InferableFunction derives type information by reflecting on the subclass's apply(Object) method. If the subclass neither overrides apply nor passes a ProcessFunction/SerializableFunction to the constructor, reflection finds only InferableFunction's own abstract apply, and the constructor throws IllegalStateException because no function body exists to infer types from or invoke.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/InferableFunction.java:52
@SuppressWarnings({
"nullness" // TODO(https://github.com/apache/beam/issues/20497)
})
public abstract class InferableFunction<InputT, OutputT>
implements ProcessFunction<InputT, OutputT>, HasDisplayData {
private final @Nullable ProcessFunction<InputT, OutputT> fn;
protected InferableFunction() {
this.fn = null;
// A subclass must override apply if using this constructor. Check that via
// reflection.
try {
Method methodThatMustBeOverridden =
InferableFunction.class.getDeclaredMethod("apply", Object.class);
Method methodOnSubclass = getClass().getMethod("apply", Object.class);
if (methodOnSubclass.equals(methodThatMustBeOverridden)) {
throw new IllegalStateException(
"Subclass of InferableFunction must override 'apply' method"
+ " or pass a ProcessFunction to the constructor,"
+ " usually via a lambda or method reference.");
}
} catch (NoSuchMethodException exc) {
throw new RuntimeException("Impossible state: missing 'apply' method entirely", exc);
}
}
protected InferableFunction(ProcessFunction<InputT, OutputT> fn) {
this.fn = fn;
}
@Override
public OutputT apply(InputT input) throws Exception {
return fn.apply(input);
}View on GitHub (pinned to 12126d8942)
Solutions
- Pass a lambda or method reference to the constructor, e.g. new InferableFunction<InputT, OutputT>(input -> transform(input))
- Override apply in the anonymous/derived class: new InferableFunction<InputT, OutputT>() { public OutputT apply(InputT input) {...} }
- Prefer the modern replacement: MapElements.via(new SimpleFunction<InputT, OutputT>() {...}) or a lambda with TypeDescriptors
- Check the method signature matches exactly apply(Object)-erased, i.e. public OutputT apply(InputT input) with no typos
- Catch IllegalStateException at construction time to fail fast with a clearer application-level message
Example fix
// before
new InferableFunction<String, Integer>() { } // no apply override
// after
new InferableFunction<String, Integer>(s -> s.length()); Defensive patterns
Strategy: type-guard
Validate before calling
if (fn.getClass().getMethod("apply", Object.class).getDeclaringClass() == InferableFunction.class) {
throw new IllegalArgumentException("Pass a lambda or override apply");
} Type guard
static boolean hasApplyOverride(InferableFunction<?, ?> fn) throws NoSuchMethodException {
return !fn.getClass()
.getMethod("apply", Object.class)
.getDeclaringClass()
.equals(InferableFunction.class);
} Try / catch
try {
InferableFunction<I,O> fn = new InferableFunction<I,O>() { };
} catch (IllegalStateException e) {
if (e.getMessage().contains("must override 'apply'")) { /* supply lambda/override */ }
else throw e;
} Prevention
- Prefer lambdas or SimpleFunction over anonymous InferableFunction subclasses
- Verify the override signature is exactly apply(Object)-compatible
- Replace InferableFunction usages with MapElements.via(new SimpleFunction<>...)
When it happens
Trigger: new InferableFunction<...>() { } with no apply override and no constructor argument; anonymous subclass that only overrides other methods; calling the no-arg protected constructor path without supplying a function.
Common situations: Migrating old MapElements/Via code that used anonymous InferableFunction subclasses to lambdas; typos where the method is named Apply or has a different signature so it doesn't override apply(Object); copying boilerplate that left the class body empty.
Understand the failure class
Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.
Related errors
- Standard logical type '%s' does not have a zero-argument con
- error when invoking Coder factory method
- cannot register Coder : does not have an accessible method n
- cannot register Coder : method named 'of' with arguments of
- cannot register Coder : method named 'of' with arguments of
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/10c9949c9949574a.
Report an issue: GitHub.