{"record":{"id":"ac6ccdb4dbc12832","repo":"apache/beam","slug":"config-class-must-be-not-null","errorCode":null,"errorMessage":"Config class must be not null!","messagePattern":"Config class must be not null!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/cdap/src/main/java/org/apache/beam/sdk/io/cdap/PluginConfigInstantiationUtils.java","lineNumber":56,"sourceCode":"public class PluginConfigInstantiationUtils {\n\n  private static final Logger LOG = LoggerFactory.getLogger(PluginConfigInstantiationUtils.class);\n  private static final String MACRO_FIELDS_FIELD_NAME = \"macroFields\";\n\n  /**\n   * Method for instantiating {@link PluginConfig} object of specific class {@code configClass}.\n   * After instantiating, it will go over all {@link Field}s with the {@link Name} annotation and\n   * set the appropriate parameter values from the {@code params} map for them.\n   *\n   * @param params map of config fields, where key is the name of the field, value must be String or\n   *     boxed primitive\n   * @return Config object for given map of arguments and configuration class\n   */\n  static @Nullable <T extends PluginConfig> T getPluginConfig(\n      Map<String, Object> params, Class<T> configClass) {\n    // Validate configClass\n    if (configClass == null) {\n      throw new IllegalArgumentException(\"Config class must be not null!\");\n    }\n    List<Field> allFields = new ArrayList<>();\n    Class<?> currClass = configClass;\n    while (currClass != null && !currClass.equals(Object.class)) {\n      allFields.addAll(\n          Arrays.stream(currClass.getDeclaredFields())\n              .filter(f -> !Modifier.isStatic(f.getModifiers()))\n              .collect(Collectors.toList()));\n      currClass = currClass.getSuperclass();\n    }\n    InstantiatorFactory instantiatorFactory = new InstantiatorFactory(false);\n\n    @Initialized T config = instantiatorFactory.get(TypeToken.of(configClass)).create();\n\n    if (config != null) {\n      for (Field field : allFields) {\n        field.setAccessible(true);\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/cdap/src/main/java/org/apache/beam/sdk/io/cdap/PluginConfigInstantiationUtils.java#L38-L74","documentation":"PluginConfigInstantiationUtils.getPluginConfig validates that the PluginConfig subclass passed for reflective instantiation is non-null before walking its field hierarchy. A null configClass would make reflection impossible, so an IllegalArgumentException is thrown immediately.","triggerScenarios":"Calling getPluginConfig(params, null) — typically from a CDAP IO wrapper whose config class was resolved to null, e.g., a generic type parameter that could not be resolved, or a Plugin.of(...) call where the config class argument was null.","commonSituations":"Passing null because a generic config type was erased or not captured; accidentally passing the plugin class's config field value (null at that point) instead of the class itself; miswiring a builder where the config class is set later than first use.","solutions":["Pass the concrete PluginConfig subclass (e.g., MyPluginConfig.class) instead of null","If the config class comes from generics, capture it explicitly via a TypeToken or pass the Class literal at the call site","Check the builder/factory that supplies configClass for a code path that leaves it unset"],"exampleFix":"// before\nPluginConfig config = PluginConfigInstantiationUtils.getPluginConfig(params, null);\n// after\nPluginConfig config = PluginConfigInstantiationUtils.getPluginConfig(params, MyPluginConfig.class);","handlingStrategy":"type-guard","validationCode":"if (configClass == null) {\n  throw new IllegalArgumentException(\"configClass must be provided to getPluginConfig\");\n}","typeGuard":"static <T extends PluginConfig> boolean validConfigClass(Class<T> c) {\n  return c != null && PluginConfig.class.isAssignableFrom(c);\n}","tryCatchPattern":"try {\n  return PluginConfigInstantiationUtils.getPluginConfig(params, configClass);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Config class must be not null\")) { /* resolve config class from generics */ }\n  throw e;\n}","preventionTips":["Pass explicit Class literals (MyConfig.class) rather than resolving from erased generics","Default unresolved generic config types via TypeToken at construction time","Never pass a config *instance* field where a Class is expected"],"tags":["java","cdap","beam","null-argument","reflection"],"backgroundTag":"null-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-15T13:17:12.816Z"}