sgl-project/sglang · error · ValueError

unsupported audio item: loaded={loaded_type}, raw={raw_type}

Error message

unsupported audio item: loaded={loaded_type}, raw={raw_type}

What it means

Raised in process_mm_data_async when an audio item's loaded value and raw value match none of the accepted shapes: raw not a dict with 'url', not str/bytes/torch.Tensor, after the loaded-type branches also failed. The message reports both the loaded and raw types for diagnosis.

Source

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

                        self._make_video_content(
                            video_tuple,
                            use_audio,
                            raw_video_item_audio,
                            preprocess_kwargs,
                        )
                    )
                elif modality == Modality.AUDIO:
                    loaded_audio = next(loaded_audio_iter)
                    raw_audio_item = next(raw_audio_iter)

                    if isinstance(loaded_audio, np.ndarray):
                        audio_source = loaded_audio
                    elif isinstance(raw_audio_item, dict):
                        audio_source = raw_audio_item.get("url", loaded_audio)
                    elif isinstance(raw_audio_item, (str, bytes, torch.Tensor)):
                        audio_source = raw_audio_item
                    else:
                        raise ValueError(
                            f"unsupported audio item: loaded={type(loaded_audio).__name__}, "
                            f"raw={type(raw_audio_item).__name__}"
                        )

                    contents.append(
                        Content(
                            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:

View on GitHub (pinned to 0132848349)

Solutions

  1. Send audio as a URL string, raw bytes, or a torch.Tensor waveform
  2. If using a dict, use exactly {'url': ...}
  3. Check the loaded={...} raw={...} types in the message to see which entry is malformed

Example fix

# before
audio = {'path': '/tmp/a.wav'}          # unsupported key
# after
audio = {'url': 'https://example.com/a.wav'}
# or: audio = open('/tmp/a.wav','rb').read()
Defensive patterns

Strategy: type-guard

Validate before calling

import torch
def is_supported_audio(a) -> bool:
    return isinstance(a, (str, bytes, torch.Tensor)) or (isinstance(a, dict) and isinstance(a.get('url'), str))

Type guard

from typing import Union, TypeGuard
import torch
def is_supported_audio_item(a) -> TypeGuard[Union[str, bytes, torch.Tensor, dict]]:
    return isinstance(a, (str, bytes, torch.Tensor)) or \
           (isinstance(a, dict) and isinstance(a.get('url'), str))

Try / catch

try:
    out = await epd.process_mm_data_async(text, audios=audios)
except ValueError as e:
    if 'unsupported audio item' in str(e):
        audios = [a['url'] if isinstance(a, dict) else a for a in audios]  # normalize, retry
        out = await epd.process_mm_data_async(text, audios=audios)
    else:
        raise

Prevention

When it happens

Trigger: Sending an audios=[...] entry that is, e.g., a list of chunks, a dict without 'url' (like {'path': ...} or {'base64': ...}), a numpy array, or None, where the loaded form also isn't a handled type.

Common situations: Client schema drift (using 'path' or 'data' keys instead of 'url'); sending audio as numpy float arrays; None entries from upstream parsing; version mismatches in the audio request format.

Related errors


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