apache/beam · error · IllegalStateException
Combine.GroupedValues requires its input values to use…
Error message
Combine.GroupedValues requires its input values to use IterableCoder
What it means
Combine.GroupedValues requires the value side of the input KvCoder to be an IterableCoder, since its input is KV<K, Iterable<V>> after grouping. When the value coder is any other coder (e.g. a ListCoder, or a raw element coder), Beam throws IllegalStateException because it cannot extract the element coder needed to build the output coder.
Solutions
- Produce the input with GroupByKey so the value coder is IterableCoder<V>.
- If setting coders manually, use IterableCoder.of(elemCoder) for the value side, not ListCoder.
- Reorder: apply GroupedValues only to the output of GroupByKey (or GroupByKey-derived transforms like Combine.perKey).
- For list-valued inputs, switch the value coder to IterableCoder.of(...), which GroupedValues recognizes.
Example fix
// before kvInput.setCoder(KvCoder.of(StringUtf8Coder.of(), ListCoder.of(VarIntCoder.of()))); kvInput.apply(Combine.groupedValues(sumFn)); // after kvInput.setCoder(KvCoder.of(StringUtf8Coder.of(), IterableCoder.of(VarIntCoder.of()))); kvInput.apply(Combine.groupedValues(sumFn));
Defensive patterns
Strategy: type-guard
Validate before calling
Coder<?> valCoder = ((KvCoder<?,?>) grouped.getCoder()).getValueCoder(); if (!(valCoder instanceof IterableCoder)) { throw new IllegalStateException("value coder must be IterableCoder, got " + valCoder); } Type guard
boolean hasIterableValueCoder(PCollection<?> pc) { return pc.getCoder() instanceof KvCoder && ((KvCoder<?,?>) pc.getCoder()).getValueCoder() instanceof IterableCoder; } Try / catch
try { grouped.apply(Combine.groupedValues(fn)); } catch (IllegalStateException e) { if (e.getMessage().contains("IterableCoder")) { /* switch value coder to IterableCoder.of(elemCoder) */ } throw e; } Prevention
- Use IterableCoder (not ListCoder) for grouped-value collections
- Keep GroupByKey as the producer of GroupedValues inputs
- Assert coder types in pipeline-construction tests
When it happens
Trigger: Applying Combine.GroupedValues to a KV collection whose value coder is not IterableCoder — e.g. manually setting the coder to ListCoder, or applying GroupedValues directly to KV<K, List<V>> built by a custom transform that coded values as a list rather than an Iterable.
Common situations: Custom transforms producing grouped values with List/Collection coders instead of IterableCoder; replacing the inferred coder after GroupByKey; misuse of GroupedValues on non-grouped data.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Combine.GroupedValues requires its input to use KvCoder
- ApproximateUnique.PerKey requires its input to use KvCoder
- AvroCoder for GenericRecord requires a schema
- cannot encode a null BitSet
- cannot encode a null byte[]
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/8a4f36d82e181b0a.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Combine.java:2297
public AppliedCombineFn<? super K, ? super InputT, ?, OutputT> getAppliedFn(
CoderRegistry registry,
Coder<? extends KV<K, ? extends Iterable<InputT>>> inputCoder,
WindowingStrategy<?, ?> windowingStrategy) {
KvCoder<K, InputT> kvCoder = getKvCoder(inputCoder);
return AppliedCombineFn.withInputCoder(fn, registry, kvCoder, sideInputs, windowingStrategy);
}
private KvCoder<K, InputT> getKvCoder(
Coder<? extends KV<K, ? extends Iterable<InputT>>> inputCoder) {
if (!(inputCoder instanceof KvCoder)) {
throw new IllegalStateException("Combine.GroupedValues requires its input to use KvCoder");
}
@SuppressWarnings({"unchecked", "rawtypes"})
KvCoder<K, ? extends Iterable<InputT>> kvCoder = (KvCoder) inputCoder;
Coder<K> keyCoder = kvCoder.getKeyCoder();
Coder<? extends Iterable<InputT>> kvValueCoder = kvCoder.getValueCoder();
if (!(kvValueCoder instanceof IterableCoder)) {
throw new IllegalStateException(
"Combine.GroupedValues requires its input values to use " + "IterableCoder");
}
@SuppressWarnings("unchecked")
IterableCoder<InputT> inputValuesCoder = (IterableCoder<InputT>) kvValueCoder;
Coder<InputT> inputValueCoder = inputValuesCoder.getElemCoder();
return KvCoder.of(keyCoder, inputValueCoder);
}
@Override
public void populateDisplayData(DisplayData.Builder builder) {
super.populateDisplayData(builder);
Combine.populateDisplayData(builder, fn, fnDisplayData);
}
}
}
View on GitHub (pinned to 12126d8942)