{"record":{"id":"d088cdabb4919986","repo":"apache/beam","slug":"a-datasourceconfiguration-or-datasourceproviderfn-has","errorCode":null,"errorMessage":"A dataSourceConfiguration or dataSourceProviderFn has already been provided, and does not need to be provided again.","messagePattern":"A dataSourceConfiguration or dataSourceProviderFn has already been provided, and does not need to be provided again\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/jdbc/src/main/java/org/apache/beam/sdk/io/jdbc/JdbcIO.java","lineNumber":1233,"sourceCode":"\n      abstract Builder<ParameterT, OutputT> setFetchSize(int fetchSize);\n\n      abstract Builder<ParameterT, OutputT> setOutputParallelization(boolean outputParallelization);\n\n      abstract Builder<ParameterT, OutputT> setDisableAutoCommit(boolean disableAutoCommit);\n\n      abstract ReadAll<ParameterT, OutputT> build();\n    }\n\n    public ReadAll<ParameterT, OutputT> withDataSourceConfiguration(\n        DataSourceConfiguration config) {\n      return withDataSourceProviderFn(new DataSourceProviderFromDataSourceConfiguration(config));\n    }\n\n    public ReadAll<ParameterT, OutputT> withDataSourceProviderFn(\n        SerializableFunction<Void, DataSource> dataSourceProviderFn) {\n      if (getDataSourceProviderFn() != null) {\n        throw new IllegalArgumentException(\n            \"A dataSourceConfiguration or dataSourceProviderFn has \"\n                + \"already been provided, and does not need to be provided again.\");\n      }\n      return toBuilder().setDataSourceProviderFn(dataSourceProviderFn).build();\n    }\n\n    public ReadAll<ParameterT, OutputT> withQuery(String query) {\n      checkArgument(query != null, \"JdbcIO.readAll().withQuery(query) called with null query\");\n      return withQuery(ValueProvider.StaticValueProvider.of(query));\n    }\n\n    public ReadAll<ParameterT, OutputT> withQuery(ValueProvider<String> query) {\n      checkArgument(query != null, \"JdbcIO.readAll().withQuery(query) called with null query\");\n      return toBuilder().setQuery(query).build();\n    }\n\n    /**\n     * Sets the {@link PreparedStatementSetter} to set the parameters of the query for each input","sourceCodeStart":1215,"sourceCodeEnd":1251,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/jdbc/src/main/java/org/apache/beam/sdk/io/jdbc/JdbcIO.java#L1215-L1251","documentation":"JdbcIO.ReadAll allows the data source to be supplied either as a DataSourceConfiguration or as a SerializableFunction provider fn, but only once. Calling withDataSourceProviderFn when one is already set (including implicitly via withDataSourceConfiguration) throws IllegalArgumentException.","triggerScenarios":"Chaining .withDataSourceConfiguration(cfg).withDataSourceProviderFn(fn) — the first call already populates dataSourceProviderFn via DataSourceProviderFromDataSourceConfiguration, so the second setter rejects the pipeline.","commonSituations":"Copy-pasted builder options; merging two builder code paths that each set a data source; refactoring from DataSourceConfiguration to a custom provider without removing the original call.","solutions":["Remove the redundant withDataSourceConfiguration/withDataSourceProviderFn call, keeping only one","If you need a custom provider, use only withDataSourceProviderFn; if you have a config object, use only withDataSourceConfiguration","Guard the builder programmatically: check which setter applies to your case before building the transform"],"exampleFix":"// before\nJdbcIO.<KV<String, Row>>readAll()\n    .withDataSourceConfiguration(config)\n    .withDataSourceProviderFn(myFn)\n    .withQuery(query);\n// after\nJdbcIO.<KV<String, Row>>readAll()\n    .withDataSourceConfiguration(config)\n    .withQuery(query);","handlingStrategy":"validation","validationCode":"if (dataSourceConfig != null && customProviderFn != null) {\n  throw new IllegalArgumentException(\"Provide only one of dataSourceConfiguration / dataSourceProviderFn\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return readAll.withDataSourceProviderFn(fn);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"dataSourceConfiguration or dataSourceProviderFn\")) {\n    return readAll; // one is already set; use the existing transform\n  }\n  throw e;\n}","preventionTips":["Choose one data-source mechanism per JdbcIO builder and document it","Search builder chains for duplicate with* calls during code review","Centralize JdbcIO transform construction in one factory method"],"tags":["jdbc","builder-validation","beam"],"backgroundTag":"conflicting-config-options","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}