apache/beam · error · IllegalArgumentException

Unable to determine accumulator coder for

Error message

Unable to determine accumulator coder for {} from {}

What it means

StateSpecs.combiningFromInputInternal() infers the accumulator coder by calling CombineFn.getAccumulatorCoder() against the standard CoderRegistry. When the CombineFn cannot provide an accumulator coder given the input coder (CannotProvideCoderException), Beam wraps it in an IllegalArgumentException naming the CombineFn class and input coder. Without an accumulator coder the CombiningState cannot be serialized.

Solutions

  1. Override getAccumulatorCoder(CoderRegistry, Coder<InputT>) in your CombineFn and return an explicit accumulator coder.
  2. Register a CoderProvider for the accumulator type, or annotate the accumulator class with @DefaultCoder(...).
  3. Use the StateSpecs.combining(accumCoder, combineFn) overload that supplies the accumulator coder explicitly.

Example fix

// before
class MyFn extends CombineFn<Long, Accum, Long> { /* no getAccumulatorCoder */ }

// after
@Override
public Coder<Accum> getAccumulatorCoder(CoderRegistry registry, Coder<Long> inputCoder) {
  return accumulatorCoder;
}
Defensive patterns

Strategy: validation

Validate before calling

try {
  combineFn.getAccumulatorCoder(CoderRegistry.createDefault(), inputCoder);
} catch (CannotProvideCoderException e) {
  // supply an explicit accumulator coder via StateSpecs.combining(accumCoder, combineFn)
}

Try / catch

try {
  spec = StateSpecs.combining(combineFn);
} catch (IllegalArgumentException e) {
  spec = StateSpecs.combining(explicitAccumCoder, combineFn);
}

Prevention

When it happens

Trigger: Creating a state spec via StateSpecs.combining(getCombineFn()) (or combiningFromInputInternal internally) where the CombineFn's getAccumulatorCoder throws CannotProvideCoderException — typically a custom CombineFn lacking an accumulator CoderProvider or a generic accumulator type Beam cannot infer from the input coder.

Common situations: Custom CombineFn with an accumulator type not derivable (e.g. generic class AccumT without registerCoderProvider); using combine functions over custom input types without registered coders; Avro/POJO types missing @DefaultCoder annotations.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/c64a0e7b12570e6e. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/state/StateSpecs.java:304

  /**
   * <b><i>For internal use only; no backwards-compatibility guarantees.</i></b>
   *
   * <p>Create a state spec for values that use a {@link CombineFn} to automatically merge multiple
   * {@code InputT}s into a single {@code OutputT}.
   *
   * <p>This determines the {@code Coder<AccumT>} from the given {@code Coder<InputT>}, and should
   * only be used to initialize static values.
   */
  @Internal
  public static <InputT, AccumT, OutputT>
      StateSpec<CombiningState<InputT, AccumT, OutputT>> combiningFromInputInternal(
          Coder<InputT> inputCoder, CombineFn<InputT, AccumT, OutputT> combineFn) {
    try {
      Coder<AccumT> accumCoder = combineFn.getAccumulatorCoder(STANDARD_REGISTRY, inputCoder);
      return combiningInternal(accumCoder, combineFn);
    } catch (CannotProvideCoderException e) {
      throw new IllegalArgumentException(
          "Unable to determine accumulator coder for "
              + combineFn.getClass().getSimpleName()
              + " from "
              + inputCoder,
          e);
    }
  }

  private static <InputT, AccumT, OutputT>
      StateSpec<CombiningState<InputT, AccumT, OutputT>> combiningInternal(
          Coder<AccumT> accumCoder, CombineFn<InputT, AccumT, OutputT> combineFn) {
    return new CombiningStateSpec<>(accumCoder, combineFn);
  }

  private static <InputT, AccumT, OutputT>
      StateSpec<CombiningState<InputT, AccumT, OutputT>> combiningInternal(
          Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, OutputT> combineFn) {
    return new CombiningWithContextStateSpec<>(accumCoder, combineFn);

View on GitHub (pinned to 12126d8942)