apache/beam · error · IllegalArgumentException
${this.getClass().getCanonicalName()} supports Integer, Long
Error message
${this.getClass().getCanonicalName()} supports Integer, Long, String and byte[] objects directly not for ${type} type, you must provide a Mapping use via. What it means
The per-key variant of ApproximateCountDistinct validates the encoded key/value type descriptors before wiring HllCount.Init.perKey(). When the input type is not one of the directly supported types (Integer, Long, String, byte[]), it throws IllegalArgumentException naming the offending type and instructing the developer to supply a mapping via via().
Source
Thrown at sdks/java/extensions/zetasketch/src/main/java/org/apache/beam/sdk/extensions/zetasketch/ApproximateCountDistinct.java:237
return input.apply(builder.perKey()).apply(HllCount.Extract.perKey());
}
// Boiler plate to avoid [argument] NonNull vs Nullable
Contextful<Fn<KV<K, V>, KV<K, Long>>> mapping = getMapping();
if (mapping != null) {
Coder<K> keyCoder = ((KvCoder<K, V>) input.getCoder()).getKeyCoder();
return input
.apply(
MapElements.into(
TypeDescriptors.kvs(
keyCoder.getEncodedTypeDescriptor(), TypeDescriptors.longs()))
.via(mapping))
.apply(HllCount.Init.forLongs().perKey())
.apply(HllCount.Extract.perKey());
}
throw new IllegalArgumentException(
String.format(
"%s supports Integer,"
+ " Long, String and byte[] objects directly not for %s type, you must provide a Mapping use via.",
this.getClass().getCanonicalName(), type.toString()));
}
@Override
public void populateDisplayData(DisplayData.Builder builder) {
super.populateDisplayData(builder);
ApproximateCountDistinct.populateDisplayData(builder, getPrecision());
}
}
/////////////////////////////////////////////////////////////////////////////
private static void populateDisplayData(DisplayData.Builder builder, Integer precision) {
builder.add(DisplayData.item("precision", precision).withLabel("Precision"));
}View on GitHub (pinned to 12126d8942)
Solutions
- Supply a mapping function (e.g. via kv -> kv.getValue().toString()) to convert to a supported type.
- Pre-map the PCollection with MapElements into longs/strings/bytes before perKey counting.
- Serialize unsupported values to byte[] explicitly.
- Check the message's printed type to see exactly which side (key/value) is unsupported.
Example fix
// before
kvPc.apply(ApproximateCountDistinct.<String, Double>perKey());
// after
kvPc.apply(MapElements.into(TypeDescriptors.kvs(TypeDescriptors.strings(), TypeDescriptors.longs()))
.via(kv -> KV.of(kv.getKey(), Double.doubleToLongBits(kv.getValue()))))
.apply(ApproximateCountDistinct.perKey()); Defensive patterns
Strategy: validation
Validate before calling
if (!isHllSupported(kvType.getKeyType()) || !isHllSupported(kvType.getValueType())) {
// supply mapping before perKey counting
} Type guard
boolean isHllKvSupported(TypeDescriptor<KV<?, ?>> t) {
return isHllSupported(t.getKeyType()) && isHllSupported(t.getValueType());
} Try / catch
try {
return kvPc.apply(ApproximateCountDistinct.perKey());
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("you must provide a Mapping")) { /* map key/value */ }
throw e;
} Prevention
- Verify KV key and value types both map to HllCount-supported types
- Convert Doubles via doubleToLongBits before perKey counting
- Add type assertions in pipeline construction code
When it happens
Trigger: Applying ApproximateCountDistinct perKey to a KV PCollection whose key or value type is not Integer/Long/String/byte[] and no mapping function was supplied.
Common situations: Counting distinct values per key where values are Doubles, POJOs, or Rows; schema-typed pipelines feeding Rows into HLL counting directly.
Related errors
- ${this.getClass().getCanonicalName()} supports Integer, Long
- Type not supported ${input}
- input should be array, map, numeric or row
- ${fieldType}
- Field type%s %s not supported when converting between JSON a
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/4cc2b3685dcc7092.
Report an issue: GitHub.