sgl-project/sglang · error · ValueError

reference audio is empty: {audio_path}

Error message

reference audio is empty: {audio_path}

What it means

After decoding, the reference audio waveform has zero samples — the file/segment produced no audio at all. The check runs in minimax_h3_encode_reference_audio_rows after _load_waveform returns, before resampling and VAE encoding.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/minimax_h3/reference_encoding.py:320

    start_time_seconds: float = 0.0,
    source_sample_rate: int | None = None,
) -> dict[str, Any]:
    """Encode a reference audio file into normalized channel-major rows.

    Returns {"rows": [2*T, 32] fp32 cpu, "ref_audio_t": T,
    "duration_seconds": float}.
    """
    model = audio_vae
    device = next(model.parameters()).device
    waveform, source_rate = _load_waveform(
        audio_path,
        material_chain=material_chain,
        max_duration_seconds=max_duration_seconds,
        start_time_seconds=start_time_seconds,
        source_sample_rate=source_sample_rate,
    )
    if waveform.numel() == 0:
        raise ValueError(f"reference audio is empty: {audio_path}")
    if int(source_rate) != MINIMAX_H3_AUDIO_SAMPLE_RATE:
        waveform = _audio_resampler(int(source_rate))(waveform)
    waveform = waveform.to(device)

    with (
        _AudioVAEDeterminismContext(),
        set_forward_context(current_timestep=0, attn_metadata=None),
    ):
        audio_data = model.preprocess(
            waveform.unsqueeze(1), MINIMAX_H3_AUDIO_SAMPLE_RATE
        )
        z = model.encoder(audio_data)
        if bool(getattr(model, "attn_proj", False)):
            z = model.pre_block(z.transpose(1, 2)).transpose(1, 2)
        if not hasattr(model, "mean_proj"):
            raise AttributeError(
                "audio VAE model must expose mean_proj for deterministic mean encoding"
            )

View on GitHub (pinned to 0132848349)

Solutions

  1. Verify the file has an audio stream and nonzero duration with ffprobe before submission
  2. Clamp start_time_seconds to the media duration
  3. Pre-check waveform length after a test decode and reject with a user-facing 'empty audio' message

Example fix

// before
start = 9999.0  # beyond clip end -> empty waveform

// after
start = min(start, probe_duration(path) - 0.1)
Defensive patterns

Strategy: validation

Validate before calling

import subprocess, json

def audio_has_samples(path) -> bool:
    out = subprocess.run(["ffprobe","-v","error","-select_streams","a","-show_entries","stream=duration","-of","json",path], capture_output=True)
    return b'"duration"' in out.stdout

Try / catch

try:
    minimax_h3_encode_reference_audio_rows(rows, ...)
except ValueError as e:
    if 'empty' in str(e):
        return bad_request("audio file contains no samples")
    raise

Prevention

When it happens

Trigger: An audio path pointing to an empty/silent-less file, a start_time beyond the media duration (ffmpeg seeks past the end and outputs nothing), or a video with no audio stream being treated as audio material.

Common situations: Corrupt zero-byte uploads, wrong path, trimming with an out-of-range start time, or silent videos passed through the audio chain.

Related errors


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