{"record":{"id":"7ab22e37874f7c30","repo":"sgl-project/sglang","slug":"kv-canary-writeplan-write-req-capacity-must-be-po","errorCode":null,"errorMessage":"kv-canary: WritePlan write_req_capacity must be positive, got {write_req_capacity}","messagePattern":"kv-canary: WritePlan write_req_capacity must be positive, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/kv_canary/write.py","lineNumber":57,"sourceCode":"        write_seed_slot_indices: Chain-seed slot per write req, shape [write_req_capacity], int64. Already\n            SWA-translated. -1 = no prefix (chain anchors on CANARY_CHAIN_ANCHOR).\n        write_num_valid_reqs: Active write-req count, shape [1], int32. launch_canary_write_kernel skips blocks\n            with block_id >= write_num_valid_reqs[0].\n    \"\"\"\n\n    write_offsets: torch.Tensor\n    write_seed_slot_indices: torch.Tensor\n    write_num_valid_reqs: torch.Tensor\n\n    @classmethod\n    def allocate(\n        cls,\n        *,\n        write_req_capacity: int,\n        device: torch.device,\n    ) -> WritePlan:\n        if write_req_capacity <= 0:\n            raise ValueError(\n                f\"kv-canary: WritePlan write_req_capacity must be positive, got {write_req_capacity}\"\n            )\n        return cls(\n            write_offsets=torch.empty(\n                write_req_capacity + 1, dtype=torch.int64, device=device\n            ),\n            write_seed_slot_indices=torch.empty(\n                write_req_capacity, dtype=torch.int64, device=device\n            ),\n            write_num_valid_reqs=torch.empty(1, dtype=torch.int32, device=device),\n        )\n\n    def zero_for_testing_(self) -> WritePlan:\n        \"\"\"WARN: ONLY use it when testing plan kernel. Do not use it when testing verify or\n        write kernel to avoid hiding bugs.\"\"\"\n        self.write_offsets.zero_()\n        self.write_seed_slot_indices.zero_()\n        self.write_num_valid_reqs.zero_()","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/kv_canary/write.py#L39-L75","documentation":"WritePlan.allocate requires write_req_capacity > 0 because it allocates write_offsets of size capacity+1 (CSR-style offsets) and a zero/negative capacity would produce a degenerate or negative-size tensor. It is an argument sanity check in the plan factory.","triggerScenarios":"Calling WritePlan.allocate(write_req_capacity=0, device=...) or with a negative value, typically when the value is derived from a request count that is 0 (empty batch).","commonSituations":"Running a write pass on a batch with no requests; capacity computed as len(reqs) - something that underflowed; tests with degenerate inputs.","solutions":["Skip the canary write entirely when there are no requests rather than allocating a plan","Ensure the capacity expression (e.g. num_reqs or max tokens) is >= 1 before calling","Trace where write_req_capacity comes from and fix the off-by-one/underflow"],"exampleFix":"# before\nplan = WritePlan.allocate(write_req_capacity=num_reqs, device=dev)\n# after\nplan = WritePlan.allocate(write_req_capacity=max(num_reqs, 1), device=dev) if num_reqs else None","handlingStrategy":"validation","validationCode":"if write_req_capacity <= 0:\n    return  # nothing to write\nplan = WritePlan.allocate(write_req_capacity=write_req_capacity, device=dev)","typeGuard":"def is_valid_write_capacity(c: int) -> bool:\n    return isinstance(c, int) and c > 0","tryCatchPattern":null,"preventionTips":["Treat an empty request set as a no-op instead of allocating a plan","Unit-test the 0-capacity path explicitly"],"tags":["kv-canary","argument-validation","capacity"],"backgroundTag":"invalid-argument-validation","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}