xai-org/x-algorithm · error · TypeError
register_task_generator expects a TaskGenerator subclass, go
Error message
register_task_generator expects a TaskGenerator subclass, got {cls!r} What it means
register_task_generator is a class decorator/registration function that only accepts classes deriving from TaskGenerator. It explicitly type-checks at runtime because decorators are easy to misapply to functions or instances. Passing anything that is not a TaskGenerator subclass raises TypeError.
Source
Thrown at grox/core/generators/registry.py:9
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)View on GitHub (pinned to 24c60942c5)
Solutions
- Make the decorated object a class inheriting from TaskGenerator (or PriorityTaskGenerator-compatible base).
- If you meant to register an instance factory, wrap it in a TaskGenerator subclass implementing _poll/from_config.
- Check the decorator target isn't a function or already-instantiated object.
- Verify imports: ensure the name under the decorator is the class itself.
Example fix
# before
@register_task_generator
def make_tasks(): ...
# after
@register_task_generator
class MyTaskGenerator(TaskGenerator):
TASK_GENERATOR_TYPE = "my_tasks" Defensive patterns
Strategy: type-guard
Validate before calling
from grox.core.generators.registry import register_task_generator from grox.core.generators.task_generator import TaskGenerator assert isinstance(MyGen, type) and issubclass(MyGen, TaskGenerator) register_task_generator(MyGen)
Type guard
def is_task_generator_class(obj) -> bool:
return isinstance(obj, type) and issubclass(obj, TaskGenerator) Try / catch
try:
register_task_generator(obj)
except TypeError as e:
if "TaskGenerator subclass" in str(e):
raise TypeError(f"{obj!r} must subclass TaskGenerator") from e
raise Prevention
- Only apply @register_task_generator to class definitions inheriting TaskGenerator.
- Static-type the decorator parameter so mypy catches misuse.
- Avoid refactoring registered classes into plain functions.
When it happens
Trigger: Using @register_task_generator on a plain function, an instance, or a class that doesn't inherit TaskGenerator; calling register_task_generator(TaskGenerator.some_function) or with an imported symbol that isn't the class you expected.
Common situations: Copy-pasting the decorator onto a helper function; refactoring a generator class into a factory function without removing the decorator; import shadowing where the decorated name resolves to a method or instance.
Related errors
- head registry hash {head_cfg.get('head_registry_hash')} != {
- {cls.__name__} must set TASK_GENERATOR_TYPE to be registered
- Duplicate generator registration for {key!r}: {existing.__na
- No task generator registered for type {cfg.type!r}. Register
- Did not find any files matching {file_pattern}
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/0431e0168e9c8c49.
Report an issue: GitHub.