{"record":{"id":"d795f38bddf7478b","repo":"sgl-project/sglang","slug":"no-encoder-method-found-for-modality-modality-na","errorCode":null,"errorMessage":"No encoder method found for modality '{modality_name}'","messagePattern":"No encoder method found for modality '(.+?)'","errorType":"validation","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/models/transformers.py","lineNumber":1379,"sourceCode":"                | self.weight_mapper\n            )\n\n    def _uses_mrope_positions(self) -> bool:\n        rope_scaling = getattr(self.text_config, \"rope_scaling\", None)\n        if isinstance(rope_scaling, Mapping) and \"mrope_section\" in rope_scaling:\n            return True\n        rope_type = str(getattr(self.text_config, \"rope_type\", \"\")).lower()\n        return \"mrope\" in rope_type\n\n    def pad_input_ids(self, input_ids: list[int], mm_inputs: MultimodalInputs):\n        return input_ids\n\n    def _get_modality_encoder(self, modality_name: str):\n        for name in self._mm_encoder_candidates[modality_name]:\n            fn = getattr(self.model, name, None)\n            if fn is not None:\n                return fn\n        raise AttributeError(f\"No encoder method found for modality '{modality_name}'\")\n\n    def _get_modality_dtype_device(\n        self, modality_name: str\n    ) -> tuple[Optional[torch.dtype], Optional[torch.device]]:\n        module_candidates = {\n            \"image\": (\"vision_tower\", \"vision_model\"),\n            \"video\": (\"video_tower\", \"vision_tower\", \"vision_model\"),\n            \"audio\": (\"audio_tower\", \"audio_model\", \"audio_encoder\"),\n        }\n        modules = []\n        for name in module_candidates.get(modality_name, ()):\n            module = getattr(self.model, name, None)\n            if module is not None:\n                modules.append(module)\n        modules.append(self.model)\n\n        for module in modules:\n            for param in module.parameters():","sourceCodeStart":1361,"sourceCodeEnd":1397,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/models/transformers.py#L1361-L1397","documentation":"For a multimodal input, the backend probes a list of candidate encoder method names on the HF model (e.g. get_image_features) and fails with AttributeError if none exists.","triggerScenarios":"Sending an image (or other modality) to a model whose class exposes none of the candidate encoder methods for that modality — e.g. a text-only model routed through the Transformers multimodal path, or a new encoder naming convention.","commonSituations":"Newer HF multimodal models renaming their feature methods; multi-image/video models with unlisted method names; accidentally enabling mm processing on a text model.","solutions":["Check self._mm_encoder_candidates[modality] vs dir(model) and extend the candidate list with the model's actual method name","Upgrade sglang/transformers so the candidate names match the model","Disable multimodal processing if the model is text-only"],"exampleFix":"# before\ncandidates = {\"image\": (\"get_image_features\", \"encode_image\")}\n# after\ncandidates = {\"image\": (\"get_image_features\", \"encode_image\", \"get_image_embeddings\")}","handlingStrategy":"fallback","validationCode":"cands = model._mm_encoder_candidates['image']\nassert any(hasattr(model.model, n) for n in cands), f'no encoder among {cands}'","typeGuard":"def has_encoder(m, modality='image') -> bool:\n    return any(hasattr(m, n) for n in ('get_image_features','encode_image'))","tryCatchPattern":"try:\n    fn = model._get_modality_encoder('image')\nexcept AttributeError:\n    fn = find_encoder_by_convention(model.model)","preventionTips":["Extend candidate name lists for new HF models","Test multimodal route with one sample per modality in CI"],"tags":["multimodal","transformers-backend","encoder-discovery"],"backgroundTag":"missing-modality-encoder","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}