{"record":{"id":"98559878f061ba78","repo":"sgl-project/sglang","slug":"name-must-start-with-0-and-contain-at-least-one","errorCode":null,"errorMessage":"{name} must start with 0 and contain at least one sequence","messagePattern":"(.+?) must start with 0 and contain at least one sequence","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/layers/attention/backends/ascend_fa.py","lineNumber":42,"sourceCode":") -> tuple[int, ...]:\n    if cu_seqlens is None:\n        raise ValueError(f\"{name} is required for NPU packed attention\")\n    if cu_seqlens.ndim != 1 or cu_seqlens.dtype not in (\n        torch.int32,\n        torch.int64,\n    ):\n        raise ValueError(f\"{name} must be a 1D int32 or int64 tensor\")\n    if cu_seqlens_host is not None and len(cu_seqlens_host) != cu_seqlens.numel():\n        raise ValueError(f\"{name} and its host copy must have the same length\")\n\n    boundaries = tuple(\n        int(value)\n        for value in (\n            cu_seqlens.tolist() if cu_seqlens_host is None else cu_seqlens_host\n        )\n    )\n    if len(boundaries) < 2 or boundaries[0] != 0:\n        raise ValueError(f\"{name} must start with 0 and contain at least one sequence\")\n    if boundaries[-1] != total_tokens:\n        raise ValueError(\n            f\"{name} must end at the packed token count {total_tokens}, \"\n            f\"got {boundaries[-1]}\"\n        )\n    if any(stop < start for start, stop in zip(boundaries[:-1], boundaries[1:])):\n        raise ValueError(f\"{name} must be non-decreasing\")\n    return boundaries\n\n\ndef fused_infer_attention_varlen(\n    q: torch.Tensor,\n    k: torch.Tensor,\n    v: torch.Tensor,\n    cu_seqlens_q: torch.Tensor,\n    cu_seqlens_k: torch.Tensor,\n    *,\n    cu_seqlens_q_host: Sequence[int] | None = None,","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/layers/attention/backends/ascend_fa.py#L24-L60","documentation":"After materializing boundary values, _packed_boundaries requires at least two entries (one real sequence) and that the first entry is 0. cu_seqlens is a cumulative sum convention: [0, len0, len0+len1, ...]; a tensor not starting at 0 or with fewer than 2 elements is malformed.","triggerScenarios":"Passing cu_seqlens that starts at a nonzero value (e.g. [3, 8, 12] from slicing without rebasing), or a degenerate tensor like [0] or [] (len(boundaries) < 2).","commonSituations":"Rebasing/slicing a packed batch and forgetting to subtract boundaries[0]; passing cumsum without the leading zero pad; an empty batch shortcut that still calls the kernel with a 1-element tensor.","solutions":["Rebase to start at 0: cu = cu - cu[0] when slicing a larger packed tensor","Use the standard construction: cu = torch.tensor([0] + list(torch.tensor(lens).cumsum(0)))","Skip the kernel call entirely for empty batches instead of passing [0]"],"exampleFix":"# before\ncu = full_cu[start_idx:]  # starts at nonzero offset\n# after\ncu = full_cu[start_idx:] - full_cu[start_idx]  # rebase to 0","handlingStrategy":"validation","validationCode":"assert len(boundaries) >= 2 and boundaries[0] == 0, \"cu_seqlens must start at 0 with >=2 entries\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the canonical [0] + cumsum(lengths) construction","Rebase to 0 whenever slicing a packed batch"],"tags":["npu","ascend","varlen","packed-sequences","validation"],"backgroundTag":"malformed-cumulative-seqlens","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}