{"record":{"id":"ffc48874f62b7df4","repo":"sgl-project/sglang","slug":"expected-a-string-in-the-format-module-class","errorCode":null,"errorMessage":"Expected a string in the format `<module>:<class>`","messagePattern":"Expected a string in the format `<module>:<class>`","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/registry.py","lineNumber":333,"sourceCode":"        - A :class:`torch.nn.Module` class directly referencing the model.\n        - A string in the format :code:`<module>:<class>` which can be used to\n          lazily import the model. This is useful to avoid initializing CUDA\n          when importing the model and thus the related error\n          :code:`RuntimeError: Cannot re-initialize CUDA in forked subprocess`.\n        \"\"\"\n        if model_arch in self.registered_models:\n            logger.warning(\n                \"Model architecture %s is already registered, and will be \"\n                \"overwritten by the new model class %s.\",\n                model_arch,\n                model_cls,\n            )\n\n        if isinstance(model_cls, str):\n            split_str = model_cls.split(\":\")\n            if len(split_str) != 2:\n                msg = \"Expected a string in the format `<module>:<class>`\"\n                raise ValueError(msg)\n\n            model = _LazyRegisteredModel(\n                module_name=split_str[0], class_name=split_str[1]\n            )\n        else:\n            model = _RegisteredModel.from_model_cls(model_cls)\n\n        self.registered_models[model_arch] = model\n\n    def _raise_for_unsupported(self, architectures: list[str]) -> NoReturn:\n        all_supported_archs = self.get_supported_archs()\n\n        if any(arch in all_supported_archs for arch in architectures):\n            raise ValueError(\n                f\"Model architectures {architectures} failed \"\n                \"to be inspected. Please check the logs for more details.\"\n            )\n","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/registry.py#L315-L351","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Format the string as exactly '<python.module.path>:<ClassName>', e.g. 'sglang.multimodal_gen.runtime.models.qwen2vl:Qwen2VLForConditionalGeneration'","Pass the class object itself if it is already imported","Add a unit test / startup check that splits each registry string on ':' and asserts len == 2"],"exampleFix":"// before\nregister_model('Qwen2VLForConditionalGeneration', 'models.qwen2vl:Qwen2VLForConditionalGeneration:extra')\n// after\nregister_model('Qwen2VLForConditionalGeneration', 'models.qwen2vl:Qwen2VLForConditionalGeneration')","handlingStrategy":"type-guard","validationCode":"if isinstance(target, str):\n    assert target.count(':') == 1 and all(target.split(':')), target","typeGuard":"def is_valid_lazy_ref(s: str) -> bool:\n    parts = s.split(':')\n    return len(parts) == 2 and all(p.isidentifier() or '.' in p for p in parts)","tryCatchPattern":"try:\n    register_model(arch, target)\nexcept ValueError as e:\n    raise ValueError(f'bad lazy ref {target!r}; expected <module>:<class>') from e","preventionTips":["Use a single helper to build '<module>:<class>' strings instead of hand-typing them","Prefer passing the class object when it is importable at registration time","Add a startup sanity pass over all registered lazy refs"],"tags":["registry","model-registration","lazy-import","validation"],"backgroundTag":"invalid-module-path-format","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}