{"record":{"id":"71835b6a2e68e1e4","repo":"apache/beam","slug":"could-not-determine-the-generic-type-of-the-list","errorCode":null,"errorMessage":"Could not determine the generic type of the list","messagePattern":"Could not determine the generic type of the list","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java","lineNumber":354,"sourceCode":"    if (isPrimitiveOrWrapperOrString(type)) {\n      if (!isPrimitiveOrWrapperOrString(valueFromRow.getClass())) {\n        throw new IllegalArgumentException(\n            \"Expected a Java primitive value but received \" + valueFromRow);\n      }\n      return valueFromRow;\n    } else if (type.isArray()) {\n      Class<?> arrayComponentClass = type.getComponentType();\n      return getDecodedArrayValueFromRow(arrayComponentClass, valueFromRow);\n    } else if (Collection.class.isAssignableFrom(type)) {\n      List<Object> originalList = (List) valueFromRow;\n      List<Object> decodedList = new ArrayList<>();\n      for (Object obj : originalList) {\n        if (genericType instanceof ParameterizedType) {\n          Class<?> elementType =\n              (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];\n          decodedList.add(getDecodedValueFromRow(elementType, obj, null));\n        } else {\n          throw new RuntimeException(\"Could not determine the generic type of the list\");\n        }\n      }\n      return decodedList;\n    } else if (valueFromRow instanceof Row) {\n      Row row = (Row) valueFromRow;\n      SerializableFunction<Row, ?> fromRowFunc;\n      try {\n        fromRowFunc = SCHEMA_REGISTRY.getFromRowFunction(type);\n      } catch (NoSuchSchemaException e) {\n        throw new IllegalArgumentException(\n            \"Could not determine the row function for class \" + type, e);\n      }\n      return fromRowFunc.apply(row);\n    }\n    throw new RuntimeException(\"Could not decode the value from Row \" + valueFromRow);\n  }\n\n  @SuppressWarnings(\"argument\")","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java#L336-L372","documentation":"When decoding a java.util.List constructor parameter, the decoder needs the element type from the declared generic type of the parameter. If the generic type is not a ParameterizedType (e.g. raw List or unknown Type), the element type cannot be determined and it throws RuntimeException.","triggerScenarios":"A constructor parameter is List<T> but genericTypes passed to getDecodedValueFromRow is null or a raw Class (not ParameterizedType) — e.g. generic type information was lost via erasure or the caller passed null for genericType.","commonSituations":"Constructors using raw List types; reflection over generic signatures where getGenericParameterTypes was not used; expansion payloads built by hand instead of by schema tooling.","solutions":["Declare the constructor parameter as List<ConcreteType> so the generic type is a ParameterizedType.","Ensure getParameterValues passes genericTypes[i] from getGenericParameterTypes rather than null.","Add a guard that resolves the element type from the schema field type when the generic type is not parameterized.","Catch RuntimeException in the expansion path and return a descriptive error to the requesting SDK."],"exampleFix":"// before\npublic MyTransform(List rawList) {...}\n// after\npublic MyTransform(java.util.List<String> items) {...}","handlingStrategy":"type-guard","validationCode":"Type t = genericTypes[i]; if (!(t instanceof ParameterizedType)) throw new IllegalArgumentException(\"List parameter \" + i + \" lacks generic element type\");","typeGuard":"boolean hasElementType(Type t) { return t instanceof ParameterizedType && ((ParameterizedType) t).getActualTypeArguments().length == 1 && ((ParameterizedType) t).getActualTypeArguments()[0] instanceof Class; }","tryCatchPattern":"try { decodeList(...); } catch (RuntimeException e) { throw new IllegalArgumentException(\"Declare List<ElementType> with generics retained\", e); }","preventionTips":["Never use raw List types in constructor signatures","Pass getGenericParameterTypes() results, not getClass() results","Keep -parameters/generic signature info in builds","Unit-test constructors containing generic collections"],"tags":["java","generics","type-erasure","row-decoding"],"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"}