{"record":{"id":"20aed7153032c0f2","repo":"apache/beam","slug":"collection-parameter-is-not-parameterized","errorCode":null,"errorMessage":"Collection parameter is not parameterized!","messagePattern":"Collection parameter is not parameterized!","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ReflectUtils.java","lineNumber":228,"sourceCode":"\n  /** For an array T[] or a subclass of Iterable<T>, return a TypeDescriptor describing T. */\n  public static @Nullable TypeDescriptor getIterableComponentType(TypeDescriptor valueType) {\n    TypeDescriptor componentType = null;\n    if (valueType.isArray()) {\n      Type component = valueType.getComponentType().getType();\n      if (!component.equals(byte.class)) {\n        // Byte arrays are special cased since we have a schema type corresponding to them.\n        componentType = TypeDescriptor.of(component);\n      }\n    } else if (valueType.isSubtypeOf(TypeDescriptor.of(Iterable.class))) {\n      TypeDescriptor<Iterable<?>> collection = valueType.getSupertype(Iterable.class);\n      if (collection.getType() instanceof ParameterizedType) {\n        ParameterizedType ptype = (ParameterizedType) collection.getType();\n        java.lang.reflect.Type[] params = ptype.getActualTypeArguments();\n        checkArgument(params.length == 1);\n        componentType = TypeDescriptor.of(params[0]);\n      } else {\n        throw new RuntimeException(\"Collection parameter is not parameterized!\");\n      }\n    }\n    return componentType;\n  }\n\n  public static TypeDescriptor getMapType(TypeDescriptor valueType, int index) {\n    TypeDescriptor mapType = null;\n    if (valueType.isSubtypeOf(TypeDescriptor.of(Map.class))) {\n      TypeDescriptor<Collection<?>> map = valueType.getSupertype(Map.class);\n      if (map.getType() instanceof ParameterizedType) {\n        ParameterizedType ptype = (ParameterizedType) map.getType();\n        java.lang.reflect.Type[] params = ptype.getActualTypeArguments();\n        mapType = TypeDescriptor.of(params[index]);\n      } else {\n        throw new RuntimeException(\"Map type is not parameterized! \" + map);\n      }\n    }\n    return mapType;","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ReflectUtils.java#L210-L246","documentation":"ReflectUtils.getIterableComponentType extracts the element TypeDescriptor of a collection-typed field. If the field's reflective type is not a ParameterizedType (i.e. the collection is used as a raw type with no generic parameter), it throws this RuntimeException, because Beam cannot infer the element schema without the type parameter.","triggerScenarios":"A POJO/schema field declared as raw List, raw Iterable, or raw Collection (no <T> type argument) while Beam infers its schema via ReflectUtils.getIterableComponentType.","commonSituations":"Legacy Java code with raw collection types, fields typed as List (raw) to avoid warnings suppression, or generic type info erased by declaring the field through reflection-obtained raw Classes rather than parameterized types.","solutions":["Parameterize the field type: List<String> instead of raw List.","If the type is only available as a Class, provide a TypeDescriptor with explicit generics when registering the schema.","Override schema inference by supplying an explicit Schema and coders for the field instead of relying on reflection."],"exampleFix":"// before\nprivate List items; // raw type\n// after\nprivate List<String> items;","handlingStrategy":"type-guard","validationCode":"TypeDescriptor<?> td = TypeDescriptor.of(MyPojo.class).getField(\"items\").getType();\nif (Collection.class.isAssignableFrom(td.getRawType()) && !(td.getType() instanceof java.lang.reflect.ParameterizedType)) {\n  throw new IllegalStateException(\"Collection field must declare its element type\");\n}","typeGuard":"// returns the element descriptor, or null when the collection is raw (would trigger the error)\nstatic <C extends Collection<?>> TypeDescriptor<?> elementOrNull(TypeDescriptor<C> td) {\n  return td.getType() instanceof java.lang.reflect.ParameterizedType\n      ? td.resolveType(java.util.Arrays.stream(((java.lang.reflect.ParameterizedType) td.getType()).getActualTypeArguments()).findFirst().orElse(null))\n      : null;\n}","tryCatchPattern":null,"preventionTips":["Enable IDE linting for raw types and fix all warnings.","Never declare fields as raw List/Set/Iterable in schema-mapped POJOs.","Pass explicit TypeDescriptors when classes cannot carry generics."],"tags":["java","generics","reflection","beam-schema"],"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"}