{"record":{"id":"ddaeedb0f4697481","repo":"apache/beam","slug":"extra-packages-were-already-specified","errorCode":null,"errorMessage":"Extra packages were already specified","messagePattern":"Extra packages were already specified","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/python/src/main/java/org/apache/beam/sdk/extensions/python/transforms/PythonMap.java","lineNumber":79,"sourceCode":"  public PythonMap<InputT, OutputT> withExpansionService(String expansionService) {\n    this.expansionService = expansionService;\n    return this;\n  }\n\n  /**\n   * Specifies any extra packages required by the Python function.\n   *\n   * <p>This should only be specified when using the default expansion service, i.e. when not using\n   * {@link #withExpansionService(String)} to provide an expansion service.\n   *\n   * <p>The package can either be a PyPi package or the path to a locally available Python package.\n   *\n   * @param extraPackages a list of PyPi packages. May include the version.\n   * @return A {@link PythonMap} with extra packages.\n   */\n  public PythonMap<InputT, OutputT> withExtraPackages(List<String> extraPackages) {\n    if (!this.extraPackages.isEmpty()) {\n      throw new IllegalArgumentException(\"Extra packages were already specified\");\n    }\n    this.extraPackages.addAll(extraPackages);\n    return this;\n  }\n\n  @Override\n  public PCollection<OutputT> expand(PCollection<? extends InputT> input) {\n    expansionService = (expansionService != null) ? expansionService : \"\";\n    return (PCollection<OutputT>)\n        input.apply(\n            PythonExternalTransform.from(pythonTransform, expansionService)\n                .withArgs(pythonFunction)\n                .withOutputCoder(outputCoder)\n                .withExtraPackages(this.extraPackages));\n  }\n}\n","sourceCodeStart":61,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/python/src/main/java/org/apache/beam/sdk/extensions/python/transforms/PythonMap.java#L61-L96","documentation":"This IllegalArgumentException is thrown by PythonMap.withExtraPackages when it is called more than once on the same builder-style PythonMap instance. The library enforces a single specification of extra PyPi packages so that the resulting transform configuration is unambiguous. Calling withExtraPackages a second time would either duplicate or conflict with previously set packages, so it is rejected eagerly.","triggerScenarios":"Calling withExtraPackages(...) twice on the same PythonMap instance, e.g. chained: map.withExtraPackages(a).withExtraPackages(b), where extraPackages was already populated by a first call.","commonSituations":"Builder-style pipelines where multiple layers of configuration each call withExtraPackages; merging configuration from two sources (e.g. defaults plus user options) both of which set extra packages; accidental double invocation in fluent chains.","solutions":["Call withExtraPackages only once per PythonMap instance; combine all packages into a single List<String> in the first call.","If configuration comes from multiple sources, merge the lists before calling withExtraPackages.","Create a fresh PythonMap instance if you need different package sets.","Refactor the fluent chain so only one method call sets packages."],"exampleFix":"// before\ntransform = PythonMap.<String, String>of(fn).withExtraPackages(defaultPkgs).withExtraPackages(userPkgs);\n// after\nList<String> allPkgs = new ArrayList<>(defaultPkgs);\nallPkgs.addAll(userPkgs);\ntransform = PythonMap.<String, String>of(fn).withExtraPackages(allPkgs);","handlingStrategy":"validation","validationCode":"if (!transform.hasExtraPackages()) { // guard or track locally\n  transform = transform.withExtraPackages(pkgs);\n}","typeGuard":null,"tryCatchPattern":"try {\n  transform = transform.withExtraPackages(pkgs);\n} catch (IllegalArgumentException e) {\n  // packages already set; keep existing configuration\n}","preventionTips":["Call withExtraPackages exactly once per instance.","Merge all package lists before the call.","Avoid chaining withExtraPackages calls in fluent expressions.","Centralize package configuration in one code path."],"tags":["java","builder-pattern","illegal-argument","configuration"],"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-14T16:17:12.679Z"}