{"record":{"id":"9912b6775a69c8b9","repo":"sgl-project/sglang","slug":"raggedverifylayout-requires-at-least-one-request","errorCode":null,"errorMessage":"RaggedVerifyLayout requires at least one request","messagePattern":"RaggedVerifyLayout requires at least one request","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/speculative/ragged_verify.py","lineNumber":66,"sourceCode":"    graph_num_tokens: int\n    extend_start_loc: torch.Tensor\n    qo_indptr_device: torch.Tensor\n    verify_lens_cpu: Optional[list[int]] = None\n    total_verify_tokens: Optional[int] = None\n    qo_indptr_host: Optional[torch.Tensor] = None\n    kv_indptr_host: Optional[torch.Tensor] = None\n    kv_lens_host: Optional[torch.Tensor] = None\n    max_q_len: Optional[int] = None\n    max_kv_len: Optional[int] = None\n    # Per-row upper bound (capped padded variant); rows never exceed it, so\n    # dense [bs, cap] consumers stay in bounds. None = full-coverage variant.\n    cap: Optional[int] = None\n\n    def __post_init__(self) -> None:\n        if self.verify_lens_cpu is None:\n            return\n        if not self.verify_lens_cpu:\n            raise ValueError(\"RaggedVerifyLayout requires at least one request\")\n        if min(self.verify_lens_cpu) < 1:\n            raise ValueError(\n                f\"every request must verify the anchor (verify_len >= 1), got \"\n                f\"{self.verify_lens_cpu}\"\n            )\n        if self.cap is not None and max(self.verify_lens_cpu) > self.cap:\n            raise ValueError(\n                f\"capped layout has a row exceeding cap={self.cap}: \"\n                f\"{self.verify_lens_cpu}\"\n            )\n        if self.total_verify_tokens != sum(self.verify_lens_cpu):\n            raise ValueError(\n                f\"total_verify_tokens {self.total_verify_tokens} != \"\n                f\"sum(verify_lens_cpu) {sum(self.verify_lens_cpu)}\"\n            )\n        if not (self.total_verify_tokens <= self.graph_num_tokens):\n            raise ValueError(\n                f\"total_verify_tokens {self.total_verify_tokens} exceeds \"","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/speculative/ragged_verify.py#L48-L84","documentation":"RaggedVerifyLayout is a dataclass describing the ragged (per-request variable-length) verification layout for speculative decoding. Its __post_init__ validates the layout; an empty verify_lens_cpu (an empty list, not None) means zero requests in the verify batch, which is nonsensical for a verify forward pass, so it raises ValueError.","triggerScenarios":"Constructing RaggedVerifyLayout(verify_lens_cpu=[]) or passing an empty running-batch schedule batch that produces an empty list. A None value is allowed (lazy/unset layout), but an empty sequence is not.","commonSituations":"Calling target-verify with an empty req list, e.g. after all requests finish mid-overlap-scheduling, or building the layout from a filtered batch that ends up empty in tests.","solutions":["Ensure the verify path is only entered with a non-empty batch; skip verify when len(reqs)==0","Pass verify_lens_cpu=None if constructing a placeholder layout","If writing tests, use at least one request, e.g. [1] for a one-token anchor row"],"exampleFix":"// before\nlayout = RaggedVerifyLayout(verify_lens_cpu=[], total_verify_tokens=0, graph_num_tokens=64)\n// after\nlayout = RaggedVerifyLayout(verify_lens_cpu=None)  # placeholder\n# or skip verify entirely when the batch is empty","handlingStrategy":"validation","validationCode":"if not verify_lens_cpu:\n    return  # nothing to verify; skip building the layout\nlayout = RaggedVerifyLayout(verify_lens_cpu=verify_lens_cpu, ...)","typeGuard":"def is_nonempty_verify_batch(lens: list[int] | None) -> bool:\n    return lens is None or len(lens) > 0","tryCatchPattern":null,"preventionTips":["Skip target-verify when the running batch is empty","In tests, always include at least one request in verify_lens_cpu"],"tags":["speculative-decoding","validation","batch-empty"],"backgroundTag":"empty-batch-validation","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}