xai-org/x-algorithm · error · ValueError
Duplicate generator registration for {key!r}: {existing.__na
Error message
Duplicate generator registration for {key!r}: {existing.__name__} vs {cls.__name__} What it means
The generator registry is keyed by TASK_GENERATOR_TYPE and refuses two different classes claiming the same key, because build() could not disambiguate which one to instantiate. Re-registering the exact same class is idempotent, but a second distinct class with the same type raises ValueError.
Source
Thrown at grox/core/generators/registry.py:19
from grox.config.config import TaskGeneratorConfig
from grox.core.generators.task_generator import TaskGenerator
_REGISTRY: dict[str, type[TaskGenerator]] = {}
def register_task_generator(cls: type[TaskGenerator]) -> type[TaskGenerator]:
if not (isinstance(cls, type) and issubclass(cls, TaskGenerator)):
raise TypeError(
f"register_task_generator expects a TaskGenerator subclass, got {cls!r}"
)
if not cls.TASK_GENERATOR_TYPE:
raise ValueError(
f"{cls.__name__} must set TASK_GENERATOR_TYPE to be registered"
)
key = cls.TASK_GENERATOR_TYPE
existing = _REGISTRY.get(key)
if existing is not None and existing is not cls:
raise ValueError(
f"Duplicate generator registration for {key!r}: {existing.__name__} vs {cls.__name__}"
)
_REGISTRY[key] = cls
return cls
def build(cfg: TaskGeneratorConfig) -> TaskGenerator:
cls = _REGISTRY.get(cfg.type)
if cls is None:
raise ValueError(
f"No task generator registered for type {cfg.type!r}. Registered: {sorted(_REGISTRY)}"
)
return cls.from_config(cfg)
def registered_types() -> set[str]:
return set(_REGISTRY)
View on GitHub (pinned to 24c60942c5)
Solutions
- Give the new generator a unique TASK_GENERATOR_TYPE value.
- If the class was copy-pasted, rename its type constant.
- If it's a re-register of the same logical class imported twice, normalize imports (single canonical module path) or guard with a registry check.
- Deregister/reset the registry in test setups between suites.
Example fix
# before
class GenA(TaskGenerator):
TASK_GENERATOR_TYPE = "tasks"
class GenB(TaskGenerator):
TASK_GENERATOR_TYPE = "tasks" # duplicate
# after
class GenB(TaskGenerator):
TASK_GENERATOR_TYPE = "tasks_b" Defensive patterns
Strategy: validation
Validate before calling
from grox.core.generators.registry import _REGISTRY
if cls.TASK_GENERATOR_TYPE in _REGISTRY:
assert _REGISTRY[cls.TASK_GENERATOR_TYPE] is cls, "duplicate type key" Type guard
def registration_is_unique(cls) -> bool:
from grox.core.generators.registry import _REGISTRY
existing = _REGISTRY.get(cls.TASK_GENERATOR_TYPE)
return existing is None or existing is cls Try / catch
try:
register_task_generator(cls)
except ValueError as e:
if "Duplicate generator registration" in str(e):
cls.TASK_GENERATOR_TYPE = f"{cls.TASK_GENERATOR_TYPE}_{cls.__module__}"
register_task_generator(cls)
else:
raise Prevention
- Generate TASK_GENERATOR_TYPE from the class name to guarantee uniqueness.
- Import generator modules through a single canonical path.
- Reset/clear the registry in test fixtures between suites.
When it happens
Trigger: Two TaskGenerator subclasses in the same process both set TASK_GENERATOR_TYPE to the same string; double imports of a module under different names (e.g. path + package import) creating distinct class objects; copy-pasted generator subclass that kept the parent's type constant.
Common situations: See trigger scenarios.
Related errors
- {cls.__name__} must set TASK_GENERATOR_TYPE to be registered
- No task generator registered for type {cfg.type!r}. Register
- head registry hash {head_cfg.get('head_registry_hash')} != {
- register_task_generator expects a TaskGenerator subclass, go
- No generators provided
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/64340ba553990f30.
Report an issue: GitHub.