{"record":{"id":"a4e44655ac3542dd","repo":"apache/beam","slug":"no-type-parameter-named-paramname-found-on-rawtype","errorCode":null,"errorMessage":"No type parameter named <paramName> found on <rawType>","messagePattern":"No type parameter named <paramName> found on <rawType>","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/values/TypeDescriptor.java","lineNumber":226,"sourceCode":"   * TypeVariable<? super List>} representing the formal type parameter {@code T}.\n   *\n   * <p>Do not mistake the type parameters (formal type argument list) with the actual type\n   * arguments. For example, if a class {@code Foo} extends {@code List<String>}, it does not make\n   * sense to ask for a type parameter, because {@code Foo} does not have any.\n   */\n  public final TypeVariable<Class<? super T>> getTypeParameter(String paramName) {\n    // Cannot convert TypeVariable<Class<? super T>>[] to TypeVariable<Class<? super T>>[]\n    // due to how they are used here, so the result of getTypeParameters() cannot be used\n    // without upcast.\n    Class<?> rawType = getRawType();\n    for (TypeVariable<?> param : rawType.getTypeParameters()) {\n      if (param.getName().equals(paramName)) {\n        @SuppressWarnings(\"unchecked\")\n        TypeVariable<Class<? super T>> typedParam = (TypeVariable<Class<? super T>>) param;\n        return typedParam;\n      }\n    }\n    throw new IllegalArgumentException(\n        \"No type parameter named \" + paramName + \" found on \" + getRawType());\n  }\n\n  /** Returns true if this type is assignable from the given type. */\n  public final boolean isSupertypeOf(TypeDescriptor<?> source) {\n    return token.isSupertypeOf(source.token);\n  }\n\n  /** Return true if this type is a subtype of the given type. */\n  public final boolean isSubtypeOf(TypeDescriptor<?> parent) {\n    return token.isSubtypeOf(parent.token);\n  }\n\n  /** Returns a list of argument types for the given method, which must be a part of the class. */\n  public List<TypeDescriptor<?>> getArgumentTypes(Method method) {\n    Invokable<?, ?> typedMethod = token.method(method);\n\n    List<TypeDescriptor<?>> argTypes = Lists.newArrayList();","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/values/TypeDescriptor.java#L208-L244","documentation":"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.","triggerScenarios":"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\".","commonSituations":"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.","solutions":["Ensure the TypeDescriptor is created for a generic class that declares the requested parameter, e.g. new TypeDescriptor<MyPair<K,V>>(getClass()){}","Use the correct parameter name matching the class's declaration (inspect the class's <K, V> clause)","Capture the descriptor with an anonymous subclass so full generic type information is retained"],"exampleFix":"// before\nTypeDescriptor<String> d = new TypeDescriptor<String>() {}; d.getTypeParameter(\"K\");\n// after\nclass PairFn<K, V> { TypeDescriptor<K> k = new TypeDescriptor<K>(getClass()) {}; } // declares K\nk.getTypeParameter(\"K\");","handlingStrategy":"type-guard","validationCode":"for (TypeVariable<Class<? super T>> p : rawType.getTypeParameters()) { /* verify paramName exists before calling */ }","typeGuard":"boolean hasTypeParameter(TypeDescriptor<?> d, String name) { return java.util.Arrays.stream(d.getRawType().getTypeParameters()).anyMatch(p -> p.getName().equals(name)); }","tryCatchPattern":"try { return desc.getTypeParameter(name); } catch (IllegalArgumentException e) { log.error(\"type parameter missing on \" + desc.getRawType(), e); throw e; }","preventionTips":["Always create TypeDescriptors via anonymous subclasses to capture generics","Match parameter names to the class's declared type variables","Avoid raw types when using generic descriptor helpers"],"tags":["java","generics","reflection","apache-beam"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}