apache/beam · error · ValueError
is already registered for specifiable class . Please…
Error message
{spec_type} is already registered for specifiable class {_KNOWN_SPECIFIABLE[subspace][spec_type]}. Please specify a different spec_type by @specifiable(spec_type=...). What it means
_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.
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)
Example fix
// before @specifiable class ZScore(AnomalyDetector): ... // after @specifiable(spec_type='myproject.ZScore') class ZScore(AnomalyDetector): ...
Defensive patterns
Strategy: validation
Validate before calling
from apache_beam.ml.anomaly.specifiable import _KNOWN_SPECIFIABLE, _class_to_subspace
sub = _class_to_subspace(MyClass)
for st, cls in _KNOWN_SPECIFIABLE[sub].items():
if cls is not MyClass and st == 'mytype':
raise RuntimeError(f'spec_type {st} taken by {cls}') Try / catch
try:
register_class(MyClass)
except ValueError as e:
logging.warning('spec_type collision: %s — using namespaced spec_type', e)
register_namespaced(MyClass) Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- ' ' not registered as Specifiable. Decorate ( ) with…
- A BigQuery table or a query must be specified
- A cluster_identifier should be Optional[Union[str…
- A context manager constructor (not a fully constructed…
- A has been supplied to the model handler, but the required…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/23261f5810d5f7b4.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/ml/anomaly/specifiable.py:243
os.path.basename(cls.__code__.co_filename), cls.__code__.co_firstlineno)
return spec_type
# Register a `Specifiable` subclass in `KNOWN_SPECIFIABLE`
def _register(cls: type, spec_type=None, inject_spec_type=True) -> None:
assert spec_type is None or inject_spec_type, \
"need to inject spec_type to class if spec_type is not None"
if spec_type is None:
# Use default spec_type for a class if users do not specify one.
spec_type = _get_default_spec_type(cls)
subspace = _class_to_subspace(cls)
if spec_type in _KNOWN_SPECIFIABLE[subspace]:
if cls is not _KNOWN_SPECIFIABLE[subspace][spec_type]:
# only raise exception if we register the same spec type with a different
# class
raise ValueError(
f"{spec_type} is already registered for "
f"specifiable class {_KNOWN_SPECIFIABLE[subspace][spec_type]}. "
"Please specify a different spec_type by @specifiable(spec_type=...)."
)
else:
_KNOWN_SPECIFIABLE[subspace][spec_type] = cls
if inject_spec_type:
setattr(cls, cls.__name__ + '__spec_type', spec_type)
# cls.__spec_type = spec_type
# Keep a copy of arguments that are used to call the `__init__` method when the
# object is initialized.
def _get_init_kwargs(inst, init_method, *args, **kwargs):
params = dict(
zip(inspect.signature(init_method).parameters.keys(), (None, ) + args))
del params['self']View on GitHub (pinned to 12126d8942)