{"record":{"id":"23261f5810d5f7b4","repo":"apache/beam","slug":"spec-type-is-already-registered-for-specifiable-class-known","errorCode":null,"errorMessage":"{spec_type} is already registered for specifiable class {_KNOWN_SPECIFIABLE[subspace][spec_type]}. Please specify a different spec_type by @specifiable(spec_type=...).","messagePattern":"(.+?) is already registered for specifiable class (.+?)\\. Please specify a different spec_type by @specifiable\\(spec_type=\\.\\.\\.\\)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/anomaly/specifiable.py","lineNumber":243,"sourceCode":"        os.path.basename(cls.__code__.co_filename), cls.__code__.co_firstlineno)\n\n  return spec_type\n\n\n# Register a `Specifiable` subclass in `KNOWN_SPECIFIABLE`\ndef _register(cls: type, spec_type=None, inject_spec_type=True) -> None:\n  assert spec_type is None or inject_spec_type, \\\n      \"need to inject spec_type to class if spec_type is not None\"\n  if spec_type is None:\n    # Use default spec_type for a class if users do not specify one.\n    spec_type = _get_default_spec_type(cls)\n\n  subspace = _class_to_subspace(cls)\n  if spec_type in _KNOWN_SPECIFIABLE[subspace]:\n    if cls is not _KNOWN_SPECIFIABLE[subspace][spec_type]:\n      # only raise exception if we register the same spec type with a different\n      # class\n      raise ValueError(\n          f\"{spec_type} is already registered for \"\n          f\"specifiable class {_KNOWN_SPECIFIABLE[subspace][spec_type]}. \"\n          \"Please specify a different spec_type by @specifiable(spec_type=...).\"\n      )\n  else:\n    _KNOWN_SPECIFIABLE[subspace][spec_type] = cls\n\n  if inject_spec_type:\n    setattr(cls, cls.__name__ + '__spec_type', spec_type)\n    # cls.__spec_type = spec_type\n\n\n# Keep a copy of arguments that are used to call the `__init__` method when the\n# object is initialized.\ndef _get_init_kwargs(inst, init_method, *args, **kwargs):\n  params = dict(\n      zip(inspect.signature(init_method).parameters.keys(), (None, ) + args))\n  del params['self']","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/anomaly/specifiable.py#L225-L261","documentation":"_register() maintains a global registry _KNOWN_SPECIFIABLE mapping (subspace, spec_type) -> class. Registering the same spec_type string for a DIFFERENT class is ambiguous, so it raises this ValueError to force a unique spec_type.","triggerScenarios":"Applying @specifiable to two different classes that resolve to the same spec_type (either an explicit spec_type=... collision, or the default spec_type derived from class name/module colliding with a built-in Beam specifiable class).","commonSituations":"Naming a custom detector class the same as a Beam built-in (e.g. ZScore) and decorating it; copying example code where spec_type was hardcoded; reloading modules in notebooks causing re-registration under a different class object.","solutions":["Pass a unique explicit type: @specifiable(spec_type='my_org.MyDetector')","Rename your class so its derived spec_type no longer collides","If intentional replacement is needed, delete the existing entry from apache_beam.ml.anomaly.specifiable._KNOWN_SPECIFIABLE first (advanced, discouraged)"],"exampleFix":"// before\n@specifiable\nclass ZScore(AnomalyDetector): ...\n\n// after\n@specifiable(spec_type='myproject.ZScore')\nclass ZScore(AnomalyDetector): ...","handlingStrategy":"validation","validationCode":"from apache_beam.ml.anomaly.specifiable import _KNOWN_SPECIFIABLE, _class_to_subspace\nsub = _class_to_subspace(MyClass)\nfor st, cls in _KNOWN_SPECIFIABLE[sub].items():\n    if cls is not MyClass and st == 'mytype':\n        raise RuntimeError(f'spec_type {st} taken by {cls}')","typeGuard":null,"tryCatchPattern":"try:\n    register_class(MyClass)\nexcept ValueError as e:\n    logging.warning('spec_type collision: %s — using namespaced spec_type', e)\n    register_namespaced(MyClass)","preventionTips":["Always pass explicit namespaced spec_type like @specifiable(spec_type='myorg.MyClass')","Avoid naming custom classes after Beam built-ins","Centralize all @specifiable registrations in one module to spot collisions early"],"tags":["python","apache-beam","registration","namespace-collision"],"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"}