apache/beam · error · java.lang.IllegalArgumentException

No type parameter named <paramName> found on <rawType>

Error message

No type parameter named <paramName> found on <rawType>

What it means

TypeDescriptor.getTypeParameter(paramName) searches the raw type's declared type variables for the named parameter and throws IllegalArgumentException when none matches. It is used to extract generic type arguments (e.g. the K/V of a PCollection descriptor), so the descriptor's raw type lacks the requested type parameter.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/values/TypeDescriptor.java:226

   * TypeVariable<? super List>} representing the formal type parameter {@code T}.
   *
   * <p>Do not mistake the type parameters (formal type argument list) with the actual type
   * arguments. For example, if a class {@code Foo} extends {@code List<String>}, it does not make
   * sense to ask for a type parameter, because {@code Foo} does not have any.
   */
  public final TypeVariable<Class<? super T>> getTypeParameter(String paramName) {
    // Cannot convert TypeVariable<Class<? super T>>[] to TypeVariable<Class<? super T>>[]
    // due to how they are used here, so the result of getTypeParameters() cannot be used
    // without upcast.
    Class<?> rawType = getRawType();
    for (TypeVariable<?> param : rawType.getTypeParameters()) {
      if (param.getName().equals(paramName)) {
        @SuppressWarnings("unchecked")
        TypeVariable<Class<? super T>> typedParam = (TypeVariable<Class<? super T>>) param;
        return typedParam;
      }
    }
    throw new IllegalArgumentException(
        "No type parameter named " + paramName + " found on " + getRawType());
  }

  /** Returns true if this type is assignable from the given type. */
  public final boolean isSupertypeOf(TypeDescriptor<?> source) {
    return token.isSupertypeOf(source.token);
  }

  /** Return true if this type is a subtype of the given type. */
  public final boolean isSubtypeOf(TypeDescriptor<?> parent) {
    return token.isSubtypeOf(parent.token);
  }

  /** Returns a list of argument types for the given method, which must be a part of the class. */
  public List<TypeDescriptor<?>> getArgumentTypes(Method method) {
    Invokable<?, ?> typedMethod = token.method(method);

    List<TypeDescriptor<?>> argTypes = Lists.newArrayList();

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the TypeDescriptor is created for a generic class that declares the requested parameter, e.g. new TypeDescriptor<MyPair<K,V>>(getClass()){}
  2. Use the correct parameter name matching the class's declaration (inspect the class's <K, V> clause)
  3. Capture the descriptor with an anonymous subclass so full generic type information is retained

Example fix

// before
TypeDescriptor<String> d = new TypeDescriptor<String>() {}; d.getTypeParameter("K");
// after
class PairFn<K, V> { TypeDescriptor<K> k = new TypeDescriptor<K>(getClass()) {}; } // declares K
k.getTypeParameter("K");
Defensive patterns

Strategy: type-guard

Validate before calling

for (TypeVariable<Class<? super T>> p : rawType.getTypeParameters()) { /* verify paramName exists before calling */ }

Type guard

boolean hasTypeParameter(TypeDescriptor<?> d, String name) { return java.util.Arrays.stream(d.getRawType().getTypeParameters()).anyMatch(p -> p.getName().equals(name)); }

Try / catch

try { return desc.getTypeParameter(name); } catch (IllegalArgumentException e) { log.error("type parameter missing on " + desc.getRawType(), e); throw e; }

Prevention

When it happens

Trigger: Calling typeDescriptor.getTypeParameter("T") (or via helpers like getK/getV) on a TypeDescriptor whose raw class does not declare a type variable with that exact name — e.g. a raw or non-generic class, or asking for "V" on a class with only "T".

Common situations: Applying generic helpers to non-generic subclasses; copying descriptor code from a class using different type-parameter names (T vs K/V); using raw types after erasure-sensitive refactors.

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