sgl-project/sglang · error · ValueError
x must be [1, S, C], got
Error message
x must be [1, S, C], got {list(x.shape)} What it means
The MiniMax H3 audio head expects x shaped [1, S, C]. The forward was called with another shape; check batching so the leading dim is 1.
Solutions
- Pack all sequences into a single [1, S_total, C] tensor with corresponding cu_seqlens/packed_seq_params
- If you have multiple samples, run them sequentially or use packing metadata rather than the batch dim
- Check x.unsqueeze(0) if you have a bare [S,C] tensor
Example fix
// before out = model(x=latents) # latents is [2, S, C] // after packed = torch.cat(samples, dim=1).unsqueeze(0) # [1, S_total, C] out = model(x=packed, ...)
Defensive patterns
Strategy: validation
Validate before calling
assert x.dim() == 3 and x.shape[0] == 1, f"expected [1,S,C], got {tuple(x.shape)}" Type guard
def is_packed_input(x) -> bool:
return torch.is_tensor(x) and x.dim() == 3 and x.shape[0] == 1 Prevention
- Always pack multi-sample sequences into dim 1 with cu_seqlens
- Add a shape assert in the pipeline before forward
When it happens
Trigger: Passing a [B,S,C] tensor with B>1, a 2-D [S,C] tensor, or an unbatched [S,C,1] layout to forward.
Common situations: Porting code from a batched diffusion-model API that accepted [B,S,C]; forgetting to pack/concatenate per-sample sequences into the packed [1,S,C] format.
Understand the failure class
Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.
Related errors
- input_ids must be 1-D, got
- inverse_indices must be
- keyframe_frame_indices must be omitted when keyframe cond…
- strict fl2va packed layout requires keyframe_frame_indices
- token_tags must cover the full packed sequence
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/d580a8cfb5616d96.
Report an issue: GitHub.
Appendix: source
Thrown at python/sglang/multimodal_gen/runtime/models/dits/minimax_h3.py:2440
cu_seqlens.tolist()
if raw_cu_seqlens_host is None
else raw_cu_seqlens_host
)
)
# max_seqlen_q is set to cu_seqlens[1] (`used`, the real/non-padding
# row count) by construction -- already a plain host int here, so
# ring can reuse it as real_seq_len below with no new device sync.
max_seqlen = int(self._psp_field(psp, "packed_seq_params", "max_seqlen_q"))
refiner_psp = _required_kwarg(kwargs, "refiner_packed_seq_params")
refiner_cu = self._psp_field(
refiner_psp, "refiner_packed_seq_params", "cu_seqlens_q"
).to(torch.int32)
refiner_max = int(
self._psp_field(refiner_psp, "refiner_packed_seq_params", "max_seqlen_q")
)
if x.dim() != 3 or x.shape[0] != 1:
raise ValueError(f"x must be [1, S, C], got {list(x.shape)}")
seq_len = int(x.shape[1])
if token_tags is not None and token_tags.shape[0] != seq_len:
raise ValueError(
"token_tags must cover the full packed sequence "
f"({seq_len}), got {token_tags.shape[0]}."
)
if inverse_indices.shape[0] != seq_len:
raise ValueError(
f"inverse_indices must be [{seq_len}], got {list(inverse_indices.shape)}"
)
device = x.device
if subblock_sparse_query_block_mask is not None and not isinstance(
subblock_sparse_query_block_mask, torch.Tensor
):
raise ValueError("subblock_sparse_query_block_mask must be a tensor")
self._resolve_attention_backend_once()
# Row split is 2D: ring first (an outer, contiguous ring_chunk_lenView on GitHub (pinned to 0132848349)