apache/beam · error · IllegalStateException

Cannot get type arguments for %s: must implement parameteriz

Error message

Cannot get type arguments for %s: must implement parameterized %s

What it means

LazyAggregateCombineFn.getTypeArguments walks the class hierarchy of a user's AggregateFn to find the parameterized AggregateFn<A, O> supertype and read its type arguments, deferring expensive reflection until needed. If the whole hierarchy is exhausted without a parameterized AggregateFn supertype (raw or non-generic subclass), it cannot infer input/output types and throws IllegalStateException.

Source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/LazyAggregateCombineFn.java:152

    public LazyUdafImpl(LazyAggregateCombineFn lazyFn) {
      super(lazyFn);
      this.lazyFn = lazyFn;
    }

    private Type[] getTypeArguments() {
      Class clazz = lazyFn.getAggregateFn().getClass();
      while (clazz != null) {
        for (Type genericInterface : clazz.getGenericInterfaces()) {
          if (genericInterface instanceof ParameterizedType) {
            ParameterizedType parameterizedType = ((ParameterizedType) genericInterface);
            if (parameterizedType.getRawType().equals(AggregateFn.class)) {
              return parameterizedType.getActualTypeArguments();
            }
          }
        }
        clazz = clazz.getSuperclass();
      }
      throw new IllegalStateException(
          String.format(
              "Cannot get type arguments for %s: must implement parameterized %s",
              lazyFn, AggregateFn.class.getSimpleName()));
    }

    @Override
    protected Type getInputType() {
      return getTypeArguments()[0];
    }

    @Override
    protected Type getOutputType() {
      return getTypeArguments()[2];
    }
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Declare your aggregate class with concrete type arguments: class MySum extends AggregateFn<Long, Long> { ... }.
  2. If using an intermediate base class, parameterize it too (class Base extends AggregateFn<Long, Long>; class MySum extends Base).
  3. Remove raw-type usage flagged by the compiler's unchecked warnings on your AggregateFn subclasses.
  4. Alternatively implement BeamTypeFactory/InferredJavaType style explicit type supply if your Beam version allows.

Example fix

// before
class MySum extends AggregateFn { ... } // raw type
// after
class MySum extends AggregateFn<Long, Long> { ... }
Defensive patterns

Strategy: validation

Validate before calling

static <I,O> boolean hasParameterizedAggregateFn(Class<?> c) {
  for (Class<?> k = c; k != null; k = k.getSuperclass()) {
    for (java.lang.reflect.Type t : k.getGenericSuperclass() instanceof Class
        ? new java.lang.reflect.Type[0]
        : new java.lang.reflect.Type[]{k.getGenericSuperclass()}) {
      if (t instanceof java.lang.reflect.ParameterizedType
          && ((java.lang.reflect.ParameterizedType) t).getRawType() == AggregateFn.class) return true;
    }
  }
  return false;
}

Type guard

static boolean isTypedAggregateFn(Object fn) {
  return java.lang.reflect.Array.get(fn.getClass().getGenericSuperclass() instanceof java.lang.reflect.ParameterizedType ? fn.getClass() : Object.class, 0) != null
      || fn.getClass().getGenericSuperclass() instanceof java.lang.reflect.ParameterizedType;
}

Try / catch

try {
  pipeline.apply(SqlTransform.query(...));
} catch (IllegalStateException e) {
  if (e.getMessage().contains("Cannot get type arguments")) {
    throw new IllegalArgumentException("AggregateFn subclass must extend AggregateFn<InputT, OutputT> with concrete types", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Registering an aggregate function whose class (or any superclass up to Object) does not directly extend AggregateFn<InputT, OutputT> with concrete type parameters — e.g. a raw subclass 'class MyAgg extends AggregateFn' or one extending a non-parameterized intermediate class.

Common situations: Using raw types to suppress generics warnings; inheriting via an intermediate class that was itself declared raw; migrating legacy UDAFs to the AggregateFn API without adding type parameters.

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