{"record":{"id":"99b0002821379377","repo":"apache/beam","slug":"unknown-type-of-combinefn-s","errorCode":null,"errorMessage":"Unknown type of CombineFn: %s","messagePattern":"Unknown type of CombineFn: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Combine.java","lineNumber":1910,"sourceCode":"                  CoderRegistry registry, Coder<InputOrAccum<InputT, AccumT>> accumulatorCoder)\n                  throws CannotProvideCoderException {\n                return fnWithContext.getDefaultOutputCoder(registry, inputCoder.getValueCoder());\n              }\n\n              @Override\n              public Coder<AccumT> getAccumulatorCoder(\n                  CoderRegistry registry, Coder<InputOrAccum<InputT, AccumT>> inputCoder)\n                  throws CannotProvideCoderException {\n                return accumCoder;\n              }\n\n              @Override\n              public void populateDisplayData(DisplayData.Builder builder) {\n                builder.delegate(PerKeyWithHotKeyFanout.this);\n              }\n            };\n      } else {\n        throw new IllegalStateException(\n            String.format(\"Unknown type of CombineFn: %s\", typedFn.getClass()));\n      }\n\n      // Use the provided hotKeyFanout fn to split into \"hot\" and \"cold\" keys,\n      // augmenting the hot keys with a nonce.\n      final TupleTag<KV<KV<K, Integer>, InputT>> hot = new TupleTag<>();\n      final TupleTag<KV<K, InputT>> cold = new TupleTag<>();\n      PCollectionTuple split =\n          input.apply(\n              \"AddNonce\",\n              ParDo.of(\n                      new DoFn<KV<K, InputT>, KV<K, InputT>>() {\n                        transient int nonce;\n\n                        @StartBundle\n                        public void startBundle() {\n                          // Spreading a hot key across all possible sub-keys for all bundles\n                          // would defeat the goal of not overwhelming downstream reducers","sourceCodeStart":1892,"sourceCodeEnd":1928,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Combine.java#L1892-L1928","documentation":"Combine.PerKeyWithHotKeyFanout wraps either a CombineFn or a KeyedCombineFn to split hot keys; when the typed function is neither, expand throws IllegalStateException reporting the unexpected CombineFn type.","triggerScenarios":"Calling withHotKeyFanout(...) with a fn object that is neither a CombineFn nor a KeyedCombineFn (e.g. a wrongly-typed custom class or a lambda cast to an unexpected interface).","commonSituations":"Passing a SimpleFunction or other transform fn by mistake; refactors changing a fn's base class; generic type erasure letting the wrong class reach the else branch.","solutions":["Pass a CombineFn or KeyedCombineFn instance to withHotKeyFanout","Check the class of the fn in the error message and align it with CombineFn/KeyedCombineFn","Use Combine.perKey(fn).withHotKeyFanout(...) rather than composing custom wrapper types"],"exampleFix":"// before\n.withHotKeyFanout(myRandomFunction) // not a CombineFn\n// after\n.withHotKeyFanout((CombineFn<InputT, AccumT, OutputT>) myCombineFn)","handlingStrategy":"type-guard","validationCode":"if (!(fn instanceof CombineFn) && !(fn instanceof KeyedCombineFn)) {\n  throw new IllegalArgumentException(\"withHotKeyFanout requires CombineFn or KeyedCombineFn, got \" + fn.getClass());\n}","typeGuard":"boolean isSupportedCombineFn(Object fn) {\n  return fn instanceof CombineFn || fn instanceof KeyedCombineFn;\n}","tryCatchPattern":"try {\n  return pc.apply(Combine.perKey(fn).withHotKeyFanout(hotKeyFn));\n} catch (IllegalStateException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Unknown type of CombineFn\")) {\n    LOG.error(\"Wrap the fn as a CombineFn or KeyedCombineFn; got: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["Only pass CombineFn or KeyedCombineFn instances to withHotKeyFanout","Avoid ad-hoc wrapper classes around combine functions","Add a unit test expanding the transform with the actual fn instance"],"tags":["java","combine","type-mismatch"],"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"}