sgl-project/sglang · error · ValueError

Speculative algorithm '{upper}' already registered.

Error message

Speculative algorithm '{upper}' already registered.

What it means

The speculative algorithm registry refuses double registration: if the uppercased name is already a key in _REGISTRY, register_algorithm raises ValueError. This usually means the registering module was imported twice or the register call runs at import time in a re-imported module.

Source

Thrown at python/sglang/srt/speculative/spec_registry.py:243

def register_algorithm(
    name: str,
    *,
    supports_overlap: bool = False,
    validate_server_args: Optional[ServerArgsValidator] = None,
    spec_class: Type[CustomSpecAlgo] = CustomSpecAlgo,
) -> Callable[[WorkerFactory], WorkerFactory]:
    """Return a decorator that registers a plugin algorithm under ``name``.

    Pass a ``spec_class`` subclass of ``CustomSpecAlgo`` to override any
    ``is_*()`` / ``supports_*()`` / ``create_worker`` method.
    """
    upper = name.upper()
    if upper in _reserved_names():
        raise ValueError(
            f"'{upper}' is a reserved speculative algorithm name; cannot be re-registered."
        )
    if upper in _REGISTRY:
        raise ValueError(f"Speculative algorithm '{upper}' already registered.")
    _assert_custom_spec_algo_conforms(spec_class)

    def decorator(factory: WorkerFactory) -> WorkerFactory:
        _REGISTRY[upper] = spec_class(
            name=upper,
            factory=factory,
            supports_overlap=supports_overlap,
            validate_server_args=validate_server_args,
        )
        return factory

    return decorator


def get_spec(name: Optional[str]) -> Optional[CustomSpecAlgo]:
    """Return the registered spec for ``name``, or ``None`` for builtin /
    unknown names."""
    if name is None:

View on GitHub (pinned to 0132848349)

Solutions

  1. Guard re-registration: delete _REGISTRY[NAME] in test teardown before re-importing
  2. Make the plugin idempotent: only register if name not already in the registry
  3. Fix duplicate imports (normalize import paths, avoid re-executing the entry point)

Example fix

# before
@register_algorithm('MYALGO')  # module imported twice -> raises
# after
if 'MYALGO' not in _REGISTRY:
    @register_algorithm('MYALGO')
    def factory(...): ...
Defensive patterns

Strategy: try-catch

Validate before calling

from sglang.srt.speculative.spec_registry import _REGISTRY
if 'MYALGO' in _REGISTRY:
    del _REGISTRY['MYALGO']  # e.g. in test teardown before re-import

Try / catch

try:
    register_algorithm('MYALGO')(factory)
except ValueError as e:
    if 'already registered' not in str(e):
        raise  # idempotent re-registration is fine

Prevention

When it happens

Trigger: Importing the plugin module twice (e.g. via different sys.paths or both an entry point and an explicit import), or calling register_algorithm twice with the same name in tests that don't clear _REGISTRY.

Common situations: Test suites re-registering algorithms without resetting the registry; duplicate module import under 'sglang.srt.x' and 'srt.x' style paths.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/5477bcf75f12ee19. Report an issue: GitHub.