{"record":{"id":"0e6e33ed33335075","repo":"apache/beam","slug":"unknown-type-of-fn-class-s-mapelements","errorCode":null,"errorMessage":"Unknown type of fn class %s","messagePattern":"Unknown type of fn class (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/MapElements.java","lineNumber":155,"sourceCode":"                              .getClosure()\n                              .apply(c.element(), Fn.Context.wrapProcessContext(c)));\n                    }\n                  })\n              .withSideInputs(\n                  ((Contextful<Fn<InputT, OutputT>>) fn).getRequirements().getSideInputs()));\n    } else if (fn instanceof ProcessFunction) {\n      return input.apply(\n          \"Map\",\n          ParDo.of(\n              new MapDoFn() {\n                @ProcessElement\n                public void processElement(\n                    @Element InputT element, OutputReceiver<OutputT> receiver) throws Exception {\n                  receiver.output(((ProcessFunction<InputT, OutputT>) fn).apply(element));\n                }\n              }));\n    } else {\n      throw new IllegalArgumentException(\n          String.format(\"Unknown type of fn class %s\", fn.getClass()));\n    }\n  }\n\n  /** A DoFn implementation that handles a trivial map call. */\n  @SuppressWarnings(\"unused\") // for outer\n  private abstract class MapDoFn extends DoFn<InputT, OutputT> {\n\n    /** Holds {@link MapDoFn#outer instance} of enclosing class, used by runner implementations. */\n    final MapElements<InputT, OutputT> outer = MapElements.this;\n\n    @Override\n    public void populateDisplayData(DisplayData.Builder builder) {\n      builder.delegate(MapElements.this);\n    }\n\n    @Override\n    public TypeDescriptor<InputT> getInputTypeDescriptor() {","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/MapElements.java#L137-L173","documentation":"MapElements.expand only knows how to adapt two kinds of wrapped functions (aSerializableFunction vs ProcessFunction). If the internal fn object is neither, it cannot produce a DoFn and throws. This is a defensive branch that should be unreachable for fn objects created by MapElements' own factories.","triggerScenarios":"Calling expand() on a MapElements whose fn was constructed as a type that is neither SerializableFunction-based nor ProcessFunction-based — typically only possible via reflection, custom subclasses, or corrupted serialization.","commonSituations":"Custom MapElements subclasses that bypass the standard factory methods (MapElements.via(...)); deserialization across incompatible Beam versions changing the fn wrapper class.","solutions":["Create MapElements only via the provided static via(...) factories (lambda, MethodReference, InferableFunction, or ProcessFunction)","Do not subclass MapElements or set its fn field directly","Check Beam version consistency between pipeline construction and deserialization"],"exampleFix":"// before\nnew MapElements<InputT, OutputT>(customFnWrapper) { ... }\n// after\nMapElements<InputT, OutputT> m = MapElements.via((InputT x) -> transform(x));","handlingStrategy":"validation","validationCode":"if (!(fn instanceof SerializableFunction) && !(fn instanceof ProcessFunction)) {\n  throw new IllegalArgumentException(\"fn must be created via MapElements.via\");\n}","typeGuard":"boolean isSupportedFn(Object fn) {\n  return fn instanceof ProcessFunction || fn instanceof SerializableFunction;\n}","tryCatchPattern":"try {\n  return mapElements.expand(input);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Unknown type of fn class\")) {\n    throw new IllegalStateException(\"Rebuild MapElements via MapElements.via(...)\" , e);\n  }\n  throw e;\n}","preventionTips":["Only construct MapElements via the static via(...) factories","Never subclass MapElements or assign fn directly","Keep Beam versions consistent across all modules"],"tags":["java","apache-beam","internal"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}