{"record":{"id":"522feed015ab51f4","repo":"sgl-project/sglang","slug":"unsupported-image-type-type-image","errorCode":null,"errorMessage":"Unsupported image type: {type(image)}","messagePattern":"Unsupported image type: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/configs/pipeline_configs/mova.py","lineNumber":70,"sourceCode":"    audio_vae_type: str = \"dac\"\n    boundary_ratio: float | None = 0.9\n\n    # temporal alignment: MOVA expects (num_frames - 1) % 4 == 0\n    time_division_factor: int = 4\n    time_division_remainder: int = 1\n\n    def get_model_deployment_config(self) -> ModelDeploymentConfig:\n        return ModelDeploymentConfig(\n            dit_layerwise_offload_modes=(\"auto\", \"memory\"),\n            keep_resident_min_available_gb=130,\n            keep_resident_components=(\"dit\", \"vae\"),\n        )\n\n    def _center_crop_and_resize(\n        self, image: torch.Tensor | Image.Image, target_height: int, target_width: int\n    ) -> torch.Tensor | Image.Image:\n        if not isinstance(image, (Image.Image, torch.Tensor)):\n            raise TypeError(f\"Unsupported image type: {type(image)}\")\n        if isinstance(image, Image.Image):\n            image = torch.from_numpy(np.array(image))\n\n        if image.ndim == 2:\n            image = image[..., None]\n\n        if not image.dtype.is_floating_point:\n            image = image.to(torch.float32).div(255.0)\n\n        if image.ndim == 3:\n            if image.shape[0] in (1, 3, 4) and image.shape[-1] not in (1, 3, 4):\n                image = image.unsqueeze(0)\n            else:\n                image = image.permute(2, 0, 1).unsqueeze(0)\n        elif image.ndim == 4:\n            if image.shape[1] not in (1, 3, 4) and image.shape[-1] in (1, 3, 4):\n                image = image.permute(0, 3, 1, 2)\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/configs/pipeline_configs/mova.py#L52-L88","documentation":"A preprocessing helper in the MoVA multimodal pipeline only accepts PIL Images or torch Tensors for condition images. When _center_crop_and_resize receives any other object (e.g. a numpy array, str path, or URL), it raises a TypeError naming the offending type. It is a strict input-contract check before cropping/resizing condition images.","triggerScenarios":"Calling preprocess_condition_image (MoVA pipeline) with a numpy ndarray, file path string, bytes, or None instead of a PIL.Image.Image or torch.Tensor. Loading an image with cv2.imread or np.asarray and passing it directly without converting to PIL/Tensor.","commonSituations":"Developer loads condition images with OpenCV (BGR ndarray) instead of PIL; receives a raw numpy array from a dataloader or decoded video frame; passes a lazy path/URL object assuming the pipeline will fetch it.","solutions":["Convert the input before calling: img = Image.fromarray(cv2.cvtColor(arr, cv2.COLOR_BGR2RGB)) or torch.from_numpy(arr)","If you have a path, open it with PIL: image = Image.open(path).convert('RGB')","If passing frames from numpy pipelines, wrap once at the boundary: torch.from_numpy(np.asarray(pil_or_frame))"],"exampleFix":"# before\nimage = cv2.imread('cond.jpg')  # numpy BGR\npipeline.preprocess_condition_image(image)\n\n# after\nimage = Image.fromarray(cv2.cvtColor(cv2.imread('cond.jpg'), cv2.COLOR_BGR2RGB))\npipeline.preprocess_condition_image(image)","handlingStrategy":"type-guard","validationCode":"from PIL import Image\nimport torch\n\ndef is_valid_condition_image(x):\n    return isinstance(x, (Image.Image, torch.Tensor)) and x is not None\n\nassert is_valid_condition_image(image), f\"bad type: {type(image)}\"","typeGuard":"def is_condition_image(x) -> bool:\n    return isinstance(x, (Image.Image, torch.Tensor))","tryCatchPattern":"try:\n    latents = pipeline.preprocess_condition_image(image)\nexcept TypeError as e:\n    raise ValueError(f\"Condition image must be PIL or Tensor, got {type(image)}\") from e","preventionTips":["Always load images with PIL.Image.open(path).convert('RGB') at the boundary","Wrap numpy frames once: torch.from_numpy(arr)","Add an isinstance assert before calling multimodal preprocess helpers"],"tags":["multimodal","input-validation","type-error","image-processing"],"backgroundTag":"unsupported-input-type","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}