{"record":{"id":"df4affaaebb2b376","repo":"apache/beam","slug":"found-multiple-builders-under-key-key","errorCode":null,"errorMessage":"Found multiple builders under key {key}","messagePattern":"Found multiple builders under key (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/portability/sdk_container_builder.py","lineNumber":154,"sourceCode":"    builder_cls = cls._get_subclass_by_key(container_build_engine)\n    builder = builder_cls(pipeline_options)\n    return builder._build()\n\n  @classmethod\n  def _get_subclass_by_key(cls, key: str) -> type['SdkContainerImageBuilder']:\n    available_builders = [\n        subclass for subclass in cls.get_all_subclasses()\n        if subclass._builder_key() == key\n    ]\n    if not available_builders:\n      available_builder_keys = [\n          subclass._builder_key() for subclass in cls.get_all_subclasses()\n      ]\n      raise ValueError(\n          f'Cannot find SDK builder type {key} in '\n          f'{available_builder_keys}')\n    elif len(available_builders) > 1:\n      raise ValueError(f'Found multiple builders under key {key}')\n    return available_builders[0]\n\n\nclass _SdkContainerImageLocalBuilder(SdkContainerImageBuilder):\n  \"\"\"SdkContainerLocalBuilder builds the sdk container image with local\n  docker.\"\"\"\n  @classmethod\n  def _builder_key(cls):\n    return 'local_docker'\n\n  def _invoke_docker_build_and_push(self, container_image_name):\n    try:\n      _LOGGER.info(\"Building sdk container, this may take a few minutes...\")\n      now = time.time()\n      subprocess.run(['docker', 'build', '.', '-t', container_image_name],\n                     check=True,\n                     cwd=self._temp_src_dir)\n    except subprocess.CalledProcessError as err:","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/portability/sdk_container_builder.py#L136-L172","documentation":"_get_subclass_by_key requires exactly one builder subclass per key. If more than one registered subclass returns the same _builder_key(), the lookup is ambiguous and ValueError is raised to prevent selecting the wrong builder.","triggerScenarios":"Two or more SdkContainerImageBuilder subclasses with identical _builder_key() values are importable when build_container_image resolves the key — typically caused by defining or importing duplicate subclasses in the same process.","commonSituations":"Defining a custom builder subclass that reuses a built-in key like 'local' or 'cloud_build'; importing both a patched and original module; accidental double registration from re-importing under different module paths.","solutions":["Find the duplicate subclass with the conflicting _builder_key() and remove or rename it","Give your custom subclass a unique _builder_key() value","Remove duplicate imports of modules defining builder subclasses","Check get_all_subclasses() output to identify the conflicting registrations"],"exampleFix":"// before\nclass MyBuilder(SdkContainerImageBuilder):\n  @classmethod\n  def _builder_key(cls): return 'local'\n// after\nclass MyBuilder(SdkContainerImageBuilder):\n  @classmethod\n  def _builder_key(cls): return 'my_custom_local'","handlingStrategy":"validation","validationCode":"keys = [s._builder_key() for s in SdkContainerImageBuilder.get_all_subclasses()]\ndupes = {k for k in keys if keys.count(k) > 1}\nassert not dupes, f'Duplicate builder keys registered: {dupes}'","typeGuard":"def keys_are_unique() -> bool:\n    keys = [s._builder_key() for s in SdkContainerImageBuilder.get_all_subclasses()]\n    return len(keys) == len(set(keys))","tryCatchPattern":"try:\n    builder = SdkContainerImageBuilder._get_subclass_by_key(key)\nexcept ValueError as e:\n    if 'Found multiple builders' in str(e):\n        raise RuntimeError('Conflicting custom builder registration; remove duplicates') from e\n    raise","preventionTips":["Give custom builder subclasses unique _builder_key values","Avoid importing the same builder module under two paths","Run a startup check that builder keys are unique before building images"],"tags":["apache-beam","container-image","ambiguous-lookup","registration-conflict"],"backgroundTag":"internal-invariant-violation","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"}