sgl-project/sglang · error · ValueError

Expected a string in the format `<module>:<class>`

Error message

Expected a string in the format `<module>:<class>`

What it means

register_model accepts a model class either as a type or as a lazy string '<module>:<class>'. This ValueError fires when the string does not contain exactly one colon-separated pair, so the lazy registration target is ambiguous.

Source

Thrown at python/sglang/multimodal_gen/runtime/models/registry.py:333

        - A :class:`torch.nn.Module` class directly referencing the model.
        - A string in the format :code:`<module>:<class>` which can be used to
          lazily import the model. This is useful to avoid initializing CUDA
          when importing the model and thus the related error
          :code:`RuntimeError: Cannot re-initialize CUDA in forked subprocess`.
        """
        if model_arch in self.registered_models:
            logger.warning(
                "Model architecture %s is already registered, and will be "
                "overwritten by the new model class %s.",
                model_arch,
                model_cls,
            )

        if isinstance(model_cls, str):
            split_str = model_cls.split(":")
            if len(split_str) != 2:
                msg = "Expected a string in the format `<module>:<class>`"
                raise ValueError(msg)

            model = _LazyRegisteredModel(
                module_name=split_str[0], class_name=split_str[1]
            )
        else:
            model = _RegisteredModel.from_model_cls(model_cls)

        self.registered_models[model_arch] = model

    def _raise_for_unsupported(self, architectures: list[str]) -> NoReturn:
        all_supported_archs = self.get_supported_archs()

        if any(arch in all_supported_archs for arch in architectures):
            raise ValueError(
                f"Model architectures {architectures} failed "
                "to be inspected. Please check the logs for more details."
            )

View on GitHub (pinned to 0132848349)

Solutions

  1. Format the string as exactly '<python.module.path>:<ClassName>', e.g. 'sglang.multimodal_gen.runtime.models.qwen2vl:Qwen2VLForConditionalGeneration'
  2. Pass the class object itself if it is already imported
  3. Add a unit test / startup check that splits each registry string on ':' and asserts len == 2

Example fix

// before
register_model('Qwen2VLForConditionalGeneration', 'models.qwen2vl:Qwen2VLForConditionalGeneration:extra')
// after
register_model('Qwen2VLForConditionalGeneration', 'models.qwen2vl:Qwen2VLForConditionalGeneration')
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(target, str):
    assert target.count(':') == 1 and all(target.split(':')), target

Type guard

def is_valid_lazy_ref(s: str) -> bool:
    parts = s.split(':')
    return len(parts) == 2 and all(p.isidentifier() or '.' in p for p in parts)

Try / catch

try:
    register_model(arch, target)
except ValueError as e:
    raise ValueError(f'bad lazy ref {target!r}; expected <module>:<class>') from e

Prevention

When it happens

Trigger: Calling register_model('Qwen2VLForConditionalGeneration') with no module, 'pkg.module:Cls:extra', or a path like 'pkg/module.py:Cls' with extra colons; also Windows-style paths or strings containing ':' in the module name.

Common situations: Hand-written registration entries in a plugin file; migrating registrations from an 'import path only' format to module:class format; typos when aliasing architectures to lazy classes.

Related errors


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