sgl-project/sglang · error · ValueError

Unsupported modality for EPD preprocessing: {modality}

Error message

Unsupported modality for EPD preprocessing: {modality}

What it means

Raised at the end of preprocess_for_encoder in MiMo-V2 when the requested modality is neither image nor audio (the two branches handled above). It is a terminal dispatch guard: any modality value that falls through the if/elif chain hits this ValueError.

Source

Thrown at python/sglang/srt/multimodal/processors/mimo_v2.py:638

                result["video_audio_segment_lens_flat"] = seg_lens_flat
                result["video_audio_segment_starts_flat"] = seg_starts_flat
                result["video_audio_per_video_num_units"] = per_video_num_units
            return result

        if modality == Modality.AUDIO:
            all_specs, all_lens = [], []
            for audio in mm_data:
                if isinstance(audio, np.ndarray):
                    audio = (torch.from_numpy(audio).float(), self.audio_sampling_rate)
                spec, token_len = self.audio_pipeline.preprocess_audio(audio)
                all_specs.append(spec)
                all_lens.append(token_len)
            return {
                "input_features": all_specs,
                "audio_feature_lens_raw": torch.tensor(all_lens, dtype=torch.long),
            }

        raise ValueError(f"Unsupported modality for EPD preprocessing: {modality}")

    def prepare_image_kwargs(self, image: ImageInput):
        kwargs = {}
        for k in ["min_pixels", "max_pixels"]:
            if getattr(image, k) is not None:
                kwargs[k] = getattr(image, k)
            else:
                kwargs[k] = self.default_image_processor_kwargs[k]
        return kwargs

    def prepare_video_kwargs(self, video: VideoInput | VideoAudioInput):
        kwargs = {}
        for k in ["min_pixels", "max_pixels", "total_max_pixels"]:
            if getattr(video, k) is not None:
                kwargs[k] = getattr(video, k)
            else:
                kwargs[k] = self.default_video_processor_kwargs[k]
        if video.num_frames is not None:

View on GitHub (pinned to 0132848349)

Solutions

  1. Confirm the modality you pass is Modality.IMAGE or Modality.AUDIO; route video inputs through the video pipeline (process_video) instead
  2. If you control the caller, add an explicit branch/guard so unsupported modalities are rejected earlier with a clearer message
  3. Upgrade sglang — a newer MiMo-V2 processor may implement the missing modality branch
Defensive patterns

Strategy: validation

Validate before calling

from sglang.srt.multimodal.media import Modality
assert modality in (Modality.IMAGE, Modality.AUDIO), f'EPD supports IMAGE/AUDIO only, got {modality}'

Type guard

def is_epd_modality(m) -> bool:
    return m in (Modality.IMAGE, Modality.AUDIO)

Try / catch

try:
    feats = proc.preprocess_mm_for_encoder(modality, items)
except ValueError as e:
    if 'Unsupported modality' in str(e):
        route_to_non_epd_path(items)
    else:
        raise

Prevention

When it happens

Trigger: Calling preprocess_mm_for_encoder with Modality.VIDEO (or any modality other than IMAGE/AUDIO) — the EPD preprocessing path only implements image and audio branches, so video (or an unknown enum member) reaches the raise.

Common situations: Routing video through the EPD encoder path before video support was added; enum extensions adding new modalities without updating this dispatcher; internal callers passing modality as a raw string that doesn't match either branch.

Related errors


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