apache/beam · error · IllegalArgumentException

${this.getClass().getCanonicalName()} supports Integer, Long

Error message

${this.getClass().getCanonicalName()} supports Integer, Long, String and byte[] objects directly. For other types you must provide a Mapping function.

What it means

ApproximateCountDistinct.expand natively maps only Integer, Long, String, and byte[] inputs onto HllCount sketch initializers. For any other element type, with no mapping function supplied, it throws IllegalArgumentException telling the developer a Mapping function (via) must be provided.

Source

Thrown at sdks/java/extensions/zetasketch/src/main/java/org/apache/beam/sdk/extensions/zetasketch/ApproximateCountDistinct.java:161

      if (HLL_IMPLEMENTED_TYPES.contains(type)) {

        HllCount.Init.Builder<T> builder = builderForType(type);

        return input.apply(builder.globally()).apply(HllCount.Extract.globally());
      }

      // Boiler plate to avoid  [argument] NonNull vs Nullable
      Contextful<Fn<T, Long>> mapping = getMapping();

      if (mapping != null) {
        return input
            .apply(MapElements.into(TypeDescriptors.longs()).via(mapping))
            .apply(HllCount.Init.forLongs().globally())
            .apply(HllCount.Extract.globally());
      }

      throw new IllegalArgumentException(
          String.format(
              "%s supports Integer,"
                  + " Long, String and byte[] objects directly. For other types you must provide a Mapping function.",
              this.getClass().getCanonicalName()));
    }

    @Override
    public void populateDisplayData(DisplayData.Builder builder) {
      super.populateDisplayData(builder);
      ApproximateCountDistinct.populateDisplayData(builder, getPrecision());
    }
  }

  @AutoValue
  public abstract static class PerKey<K, V>
      extends PTransform<PCollection<KV<K, V>>, PCollection<KV<K, Long>>> {

    public abstract int getPrecision();

View on GitHub (pinned to 12126d8942)

Solutions

  1. Provide a mapping function converting your type to a supported one, e.g. MapElements.into(TypeDescriptors.longs()).via(x -> x.getId()).
  2. Convert the input PCollection to strings or bytes before counting.
  3. Use a different sketch/approximation transform that supports your type natively.
  4. For perKey variants, map both key and value types to supported ones.

Example fix

// before
pc.apply(ApproximateCountDistinct.<MyPojo>globally());
// after
pc.apply(MapElements.into(TypeDescriptors.longs()).via(MyPojo::getId))
  .apply(ApproximateCountDistinct.globally());
Defensive patterns

Strategy: type-guard

Validate before calling

if (!Arrays.asList(Integer.class, Long.class, String.class, byte[].class).equals(elemType.getRawType())) {
  // require a mapping function before applying
}

Type guard

boolean isHllSupported(TypeDescriptor<?> t) {
  Class<?> c = t.getRawType();
  return c == Integer.class || c == Long.class || c == String.class || c == byte[].class;
}

Try / catch

try {
  return pc.apply(ApproximateCountDistinct.globally());
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Mapping function")) { /* supply via() mapping */ }
  throw e;
}

Prevention

When it happens

Trigger: Applying ApproximateCountDistinct.globally() (or perKey) to a PCollection of a type other than Integer/Long/String/byte[] without calling a via()/mapping overload.

Common situations: Counting distinct custom POJOs, Rows, Doubles, or Booleans directly; using the generic T-typed constructor expecting automatic conversion.

Related errors


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