apache/beam · error · IllegalArgumentException

cannot register Coder : method named 'of' with arguments of

Error message

cannot register Coder : method named 'of' with  arguments of Coder type does not return a 

What it means

getFactoryMethod verifies that the `of` method's return type is assignable to the Coder class being registered (coderClazz.isAssignableFrom(returnType)). If `of` returns some other type — e.g. raw Coder of a different class, Object, or a sibling coder type — registration fails with this IllegalArgumentException because the provider could not return a coder of the expected class.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderProviders.java:134

            "cannot register Coder "
                + coderClazz
                + ": "
                + "does not have an accessible method named 'of' with "
                + numTypeParameters
                + " arguments of Coder type",
            exn);
      }
      if (!Modifier.isStatic(factoryMethodCandidate.getModifiers())) {
        throw new IllegalArgumentException(
            "cannot register Coder "
                + coderClazz
                + ": "
                + "method named 'of' with "
                + numTypeParameters
                + " arguments of Coder type is not static");
      }
      if (!coderClazz.isAssignableFrom(factoryMethodCandidate.getReturnType())) {
        throw new IllegalArgumentException(
            "cannot register Coder "
                + coderClazz
                + ": "
                + "method named 'of' with "
                + numTypeParameters
                + " arguments of Coder type does not return a "
                + coderClazz);
      }
      try {
        if (!factoryMethodCandidate.isAccessible()) {
          factoryMethodCandidate.setAccessible(true);
        }
      } catch (SecurityException exn) {
        throw new IllegalArgumentException(
            "cannot register Coder "
                + coderClazz
                + ": "
                + "method named 'of' with "

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change `of`'s declared return type to the registering class itself: `public static <T> MyCoder<T> of(Coder<T> c)`
  2. If `of` lives in a superclass, override it in coderClazz with a covariant return type of coderClazz
  3. Ensure generics are not erased to a supertype (avoid raw `Coder` returns; use `MyCoder<T>`)
  4. Register the coder the `of` method actually builds with CoderProviders.fromStaticMethods against that class instead

Example fix

// before: inherited from base, returns base type
static <T> Coder<T> of(Coder<T> c) { return new MyCoder<>(c); }
// after: covariant override in MyCoder
public static <T> MyCoder<T> of(Coder<T> c) { return new MyCoder<>(c); }
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean ofReturnsOwnCoder(Class<?> coderClazz) throws NoSuchMethodException {
  Class<?>[] argTypes = new Class<?>[coderClazz.getTypeParameters().length];
  java.util.Arrays.fill(argTypes, Coder.class);
  return coderClazz.isAssignableFrom(
      coderClazz.getDeclaredMethod("of", argTypes).getReturnType());
}

Type guard

static boolean validFactorySignature(Class<?> coderClazz) {
  try {
    Class<?>[] argTypes = new Class<?>[coderClazz.getTypeParameters().length];
    java.util.Arrays.fill(argTypes, Coder.class);
    Method of = coderClazz.getDeclaredMethod("of", argTypes);
    return java.lang.reflect.Modifier.isStatic(of.getModifiers())
        && coderClazz.isAssignableFrom(of.getReturnType());
  } catch (NoSuchMethodException | SecurityException e) { return false; }
}

Try / catch

try {
  CoderProvider provider = CoderProviders.fromStaticMethods(rawType, coderClazz);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("does not return a")) {
    throw new IllegalStateException("of() must return " + coderClazz.getName(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: CoderProviders.fromStaticMethods(rawType, coderClazz) where coderClazz declares `static X of(Coder...)` with X not a subclass of coderClazz, e.g. `of` declared in a superclass or interface returning the supertype, or returning a different concrete Coder class.

Common situations: Putting the generic `static <T> Coder<T> of(...)` in an abstract base class and registering concrete subclasses whose inherited `of` returns the base Coder type; raw-type returns after refactoring generics; a factory that builds a different coder implementation than the registered class.

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