apache/beam · error · IllegalStateException

Could not determine coder for accumulator

Error message

Could not determine coder for accumulator

What it means

AppliedCombineFn.withInputCoder() clones the given GlobalCombineFn and asks it to infer a Coder for its accumulator via getAccumulatorCoder(registry, kvCoder.getValueCoder()). If the combine function cannot provide a coder (CannotProvideCoderException), the factory wraps it in an IllegalStateException('Could not determine coder for accumulator'). The CombineFn must be able to serialize its accumulator type for distributed execution.

Solutions

  1. Implement getAccumulatorCoder() in your CombineFn to return an explicit Coder (e.g. a SerializableCoder or custom Coder) instead of delegating/throwing.
  2. Register a default Coder for the accumulator type in the CoderRegistry (registry.registerCoder(AccumT.class, MyCoder.class)).
  3. Choose an accumulator type Beam can encode natively (KV, primitives, annotated with @DefaultSchema) so inference succeeds.

Example fix

// before
@Override public Coder<Accum> getAccumulatorCoder(CoderRegistry r, Coder<Input> in) throws CannotProvideCoderException {
  throw new CannotProvideCoderException("no coder");
}
// after
@Override public Coder<Accum> getAccumulatorCoder(CoderRegistry r, Coder<Input> in) {
  return SerializableCoder.of(Accum.class);
}
Defensive patterns

Strategy: validation

Validate before calling

CoderRegistry registry = pipeline.getCoderRegistry();
registry.registerCoderForClass(MyAccum.class, MyAccumCoder.class);
// or verify your CombineFn.getAccumulatorCoder does not throw CannotProvideCoderException

Try / catch

try {
  AppliedCombineFn.withInputCoder(fn, registry, kvCoder, sideInputs);
} catch (IllegalStateException e) {
  // fall back to a coder-explicit CombineFn implementation
}

Prevention

When it happens

Trigger: Creating an AppliedCombineFn for a custom CombineFn whose getAccumulatorCoder throws CannotProvideCoderException — typically because the accumulator class has no registered default coder and the type is not one Beam can infer (e.g. a custom POJO without an encoded schema).

Common situations: Writing a custom CombineFn with an accumulator type like Optional, an interface, or a POJO lacking a registered Coder; registry in withInputCoder(CoderRegistry, ...) not containing coders for nested accumulator types.

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/5e82104c11485db6. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/AppliedCombineFn.java:114

  }

  public static <K, InputT, AccumT, OutputT>
      AppliedCombineFn<K, InputT, AccumT, OutputT> withInputCoder(
          GlobalCombineFn<? super InputT, AccumT, OutputT> fn,
          CoderRegistry registry,
          KvCoder<K, InputT> kvCoder,
          Iterable<PCollectionView<?>> sideInputViews,
          WindowingStrategy<?, ?> windowingStrategy) {
    // Casting down the K and InputT is safe because they're only used as inputs.
    @SuppressWarnings("unchecked")
    GlobalCombineFn<InputT, AccumT, OutputT> clonedFn =
        (GlobalCombineFn<InputT, AccumT, OutputT>) SerializableUtils.clone(fn);
    try {
      Coder<AccumT> accumulatorCoder =
          clonedFn.getAccumulatorCoder(registry, kvCoder.getValueCoder());
      return create(clonedFn, accumulatorCoder, sideInputViews, kvCoder, windowingStrategy);
    } catch (CannotProvideCoderException e) {
      throw new IllegalStateException("Could not determine coder for accumulator", e);
    }
  }

  private static <K, InputT, AccumT, OutputT> AppliedCombineFn<K, InputT, AccumT, OutputT> create(
      GlobalCombineFn<InputT, AccumT, OutputT> fn,
      Coder<AccumT> accumulatorCoder,
      Iterable<PCollectionView<?>> sideInputViews,
      KvCoder<K, InputT> kvCoder,
      WindowingStrategy<?, ?> windowingStrategy) {
    return new AppliedCombineFn<>(fn, accumulatorCoder, sideInputViews, kvCoder, windowingStrategy);
  }

  public GlobalCombineFn<InputT, AccumT, OutputT> getFn() {
    return fn;
  }

  public Iterable<PCollectionView<?>> getSideInputViews() {
    return sideInputViews;

View on GitHub (pinned to 12126d8942)