sgl-project/sglang · error · ValueError

Multimodal data is corrupted or cannot be decoded: {e}

Error message

Multimodal data is corrupted or cannot be decoded: {e}

What it means

MiMo-v2 ASR processor wraps a RuntimeError from its offline audio decoding (_process_contents run on the io_executor) as 'Multimodal data is corrupted or cannot be decoded'. The underlying exception text is appended, so the real cause (bad file, unsupported codec, truncated download) is in the message tail.

Source

Thrown at python/sglang/srt/multimodal/processors/mimo_v2_asr.py:261

                            type="audio",
                            content=AudioInput(audio=audio_source),
                        )
                    )
            else:
                if text_part:
                    contents.append(_Content(type="text", content=text_part))

        loop = asyncio.get_running_loop()
        try:
            input_ids, audio_inputs, position_ids, rope_deltas = (
                await loop.run_in_executor(
                    self.io_executor,
                    lambda: self._process_contents(contents),
                )
            )
        except RuntimeError as e:
            logger.error(f"MiMo ASR processor failed in process_mm_data_async: {e}")
            raise ValueError(f"Multimodal data is corrupted or cannot be decoded: {e}")

        input_ids_flat = input_ids.flatten()
        if audio_inputs:
            mm_items = [
                MultimodalDataItem(
                    modality=Modality.AUDIO,
                    feature=audio_inputs,
                    offsets=self.get_mm_items_offset(
                        input_ids=input_ids_flat,
                        mm_token_id=self.audio_token_id,
                    ),
                )
            ]
        else:
            mm_items = []

        return MultimodalProcessorOutput(
            mm_items=mm_items,

View on GitHub (pinned to 0132848349)

Solutions

  1. Inspect the appended {e} text to identify the true decode failure
  2. Re-encode the audio to a standard format (16 kHz mono WAV/FLAC via ffmpeg) and retry
  3. Verify the file is complete and not truncated (compare sizes / re-download)
  4. If the codec is genuinely unsupported by the installed decoder, install/enable the matching backend or transcode server-side

Example fix

# before
{"audio": "https://cdn.example.com/clip.bin"}
# after
ffmpeg -i clip.bin -ar 16000 -ac 1 clip.wav
{"audio": "https://cdn.example.com/clip.wav"}
Defensive patterns

Strategy: fallback

Validate before calling

import wave
wave.open(local_path)  # quick sanity decode before upload; or:
import subprocess; assert subprocess.run(["ffprobe", path]).returncode == 0

Try / catch

try:
    resp = client.transcribe(audio)
except ValueError as e:
    if "corrupted or cannot be decoded" in str(e):
        audio = reencode_wav16k(audio)  # fallback transcode then retry once
        resp = client.transcribe(audio)
    else:
        raise

Prevention

When it happens

Trigger: process_mm_data_async submits decoding to the io_executor and the decode raises RuntimeError — corrupt audio bytes, unsupported container/codec, unreadable URL content, or a truncated file.

Common situations: Downloading audio over flaky networks producing truncated files, feeding unusual codecs (e.g. odd sample rates or containers) the decoder build does not support, or corrupted base64 payloads from client-side encoding bugs.

Related errors


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