apache/beam · error · IllegalArgumentException

Class has parameters, but coders are requested.

Error message

Class %s has %d parameters, but %d coders are requested.

What it means

CoderRegistry.getDefaultCoders validates that the number of explicitly provided knownCoders matches the number of type parameters on the generic base class. A mismatch throws IllegalArgumentException 'Class %s has %d parameters, but %d coders are requested.' — e.g. passing 2 coders to getDefaultOutputCoder on a CombineFn with 3 type parameters.

Solutions

  1. Pass an array of known coders whose length equals the number of type parameters of baseClass (e.g. 3 for CombineFn<InputT, AccT, OutT>)
  2. Use null for knownCoders to let the registry fill all positions via inference instead of supplying a wrong-length array
  3. Check baseClass's declared generic signature and count its type arguments before constructing the coder array

Example fix

// before
registry.getDefaultOutputCoder(fn, CombineFn.class, new Coder<?>[]{c1}); // CombineFn has 3 params
// after
registry.getDefaultOutputCoder(fn, CombineFn.class, new Coder<?>[]{c1, c2, c3});
Defensive patterns

Strategy: validation

Validate before calling

int typeParamCount = baseClass.getTypeParameters().length;
if (knownCoders != null && knownCoders.length != typeParamCount) throw new IllegalArgumentException("Expected " + typeParamCount + " coders");

Type guard

boolean coderCountMatches = knownCoders == null || knownCoders.length == baseClass.getTypeParameters().length;

Prevention

When it happens

Trigger: Calling getDefaultOutputCoder / getAccumulatorCoder / getDefaultCoders with a knownCoders array whose length differs from baseClass's actual type-argument count (e.g. 3 generic params on CombineFn but only 1–2 coders supplied).

Common situations: Mispredicting the number of type parameters of CombineFn/DoFn/KeyedCombineFn after a Beam version changed the class hierarchy; copy-pasted coder arrays reused across differently parameterized classes.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderRegistry.java:434

   * @param knownCoders an array corresponding to the set of base class type parameters. Each entry
   *     can be either a {@link Coder} (in which case it will be used for inference) or {@code null}
   *     (in which case it will be inferred). May be {@code null} to indicate the entire set of
   *     parameters should be inferred.
   * @throws IllegalArgumentException if baseClass doesn't have type parameters or if the length of
   *     {@code knownCoders} is not equal to the number of type parameters of {@code baseClass}.
   */
  private <T> Coder<?>[] getDefaultCoders(
      Class<? extends T> subClass, Class<T> baseClass, @Nullable Coder<?>[] knownCoders) {
    Type type = TypeDescriptor.of(subClass).getSupertype(baseClass).getType();
    if (!(type instanceof ParameterizedType)) {
      throw new IllegalArgumentException(type + " is not a ParameterizedType");
    }
    ParameterizedType parameterizedType = (ParameterizedType) type;
    Type[] typeArgs = parameterizedType.getActualTypeArguments();
    if (knownCoders == null) {
      knownCoders = new Coder<?>[typeArgs.length];
    } else if (typeArgs.length != knownCoders.length) {
      throw new IllegalArgumentException(
          String.format(
              "Class %s has %d parameters, but %d coders are requested.",
              baseClass.getCanonicalName(), typeArgs.length, knownCoders.length));
    }

    SetMultimap<Type, Coder<?>> context = HashMultimap.create();
    for (int i = 0; i < knownCoders.length; i++) {
      if (knownCoders[i] != null) {
        try {
          verifyCompatible(knownCoders[i], typeArgs[i]);
        } catch (IncompatibleCoderException exn) {
          throw new IllegalArgumentException(
              String.format(
                  "Provided coders for type arguments of %s contain incompatibilities:"
                      + " Cannot encode elements of type %s with coder %s",
                  baseClass, typeArgs[i], knownCoders[i]),
              exn);
        }

View on GitHub (pinned to 12126d8942)