{"record":{"id":"d580a8cfb5616d96","repo":"sgl-project/sglang","slug":"x-must-be-1-s-c-got-list-x-shape","errorCode":null,"errorMessage":"x must be [1, S, C], got {list(x.shape)}","messagePattern":"x must be \\[1, S, C\\], got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/dits/minimax_h3.py","lineNumber":2440,"sourceCode":"                cu_seqlens.tolist()\n                if raw_cu_seqlens_host is None\n                else raw_cu_seqlens_host\n            )\n        )\n        # max_seqlen_q is set to cu_seqlens[1] (`used`, the real/non-padding\n        # row count) by construction -- already a plain host int here, so\n        # ring can reuse it as real_seq_len below with no new device sync.\n        max_seqlen = int(self._psp_field(psp, \"packed_seq_params\", \"max_seqlen_q\"))\n        refiner_psp = _required_kwarg(kwargs, \"refiner_packed_seq_params\")\n        refiner_cu = self._psp_field(\n            refiner_psp, \"refiner_packed_seq_params\", \"cu_seqlens_q\"\n        ).to(torch.int32)\n        refiner_max = int(\n            self._psp_field(refiner_psp, \"refiner_packed_seq_params\", \"max_seqlen_q\")\n        )\n\n        if x.dim() != 3 or x.shape[0] != 1:\n            raise ValueError(f\"x must be [1, S, C], got {list(x.shape)}\")\n        seq_len = int(x.shape[1])\n        if token_tags is not None and token_tags.shape[0] != seq_len:\n            raise ValueError(\n                \"token_tags must cover the full packed sequence \"\n                f\"({seq_len}), got {token_tags.shape[0]}.\"\n            )\n        if inverse_indices.shape[0] != seq_len:\n            raise ValueError(\n                f\"inverse_indices must be [{seq_len}], got {list(inverse_indices.shape)}\"\n            )\n        device = x.device\n        if subblock_sparse_query_block_mask is not None and not isinstance(\n            subblock_sparse_query_block_mask, torch.Tensor\n        ):\n            raise ValueError(\"subblock_sparse_query_block_mask must be a tensor\")\n        self._resolve_attention_backend_once()\n\n        # Row split is 2D: ring first (an outer, contiguous ring_chunk_len","sourceCodeStart":2422,"sourceCodeEnd":2458,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/dits/minimax_h3.py#L2422-L2458","documentation":"forward requires the packed latent input x to be a 3-D tensor of shape [1, S, C] — batch dim must be exactly 1 since packing replaces batching. Any other rank or batch size raises this ValueError.","triggerScenarios":"Passing a [B,S,C] tensor with B>1, a 2-D [S,C] tensor, or an unbatched [S,C,1] layout to forward.","commonSituations":"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.","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"],"exampleFix":"// before\nout = model(x=latents)          # latents is [2, S, C]\n// after\npacked = torch.cat(samples, dim=1).unsqueeze(0)  # [1, S_total, C]\nout = model(x=packed, ...)","handlingStrategy":"validation","validationCode":"assert x.dim() == 3 and x.shape[0] == 1, f\"expected [1,S,C], got {tuple(x.shape)}\"","typeGuard":"def is_packed_input(x) -> bool:\n    return torch.is_tensor(x) and x.dim() == 3 and x.shape[0] == 1","tryCatchPattern":null,"preventionTips":["Always pack multi-sample sequences into dim 1 with cu_seqlens","Add a shape assert in the pipeline before forward"],"tags":["minimax-h3","input-shape","packed-sequence"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}