{"record":{"id":"62ed8a67086dfca2","repo":"sgl-project/sglang","slug":"kv-canary-write-offsets-len-must-equal-write-req","errorCode":null,"errorMessage":"kv-canary: write_offsets_len must equal write_req_capacity + 1, got {write_offsets_len} and {write_req_capacity}","messagePattern":"kv-canary: write_offsets_len must equal write_req_capacity \\+ 1, got (.+?) and (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/kv_canary/plan/offsets_kernel.py","lineNumber":205,"sourceCode":"    _require_min_len(lut_tensor, \"lut_tensor\", max(lut_len, 1))\n    _require_min_len(\n        out_verify_offsets_scratch,\n        \"out_verify_offsets_scratch\",\n        _PLAN_BS_BLOCK_SIZE + 1,\n    )\n    _require_len(out_write_offsets, \"out_write_offsets\", write_offsets_len)\n    _require_len(\n        out_write_seed_slot_indices,\n        \"out_write_seed_slot_indices\",\n        write_req_capacity,\n    )\n    _require_len(out_verify_num_valid, \"out_verify_num_valid\", 1)\n    _require_len(out_verify_enable, \"out_verify_enable\", 1)\n    _require_len(out_write_num_valid_reqs, \"out_write_num_valid_reqs\", 1)\n    _require_1d(lut_tensor, \"lut_tensor\")\n\n    if write_offsets_len != write_req_capacity + 1:\n        raise ValueError(\n            f\"kv-canary: write_offsets_len must equal write_req_capacity + 1, got \"\n            f\"{write_offsets_len} and {write_req_capacity}\"\n        )\n    if bs > write_req_capacity:\n        raise ValueError(\n            f\"kv-canary: bs={bs} exceeds write_req_capacity={write_req_capacity}\"\n        )\n    if req_to_token_stride0 != int(req_to_token.stride(0)):\n        raise ValueError(\n            f\"kv-canary: req_to_token_stride0={req_to_token_stride0} does not match \"\n            f\"req_to_token.stride(0)={int(req_to_token.stride(0))}\"\n        )\n\n    _require_same_device(\n        out_verify_offsets_scratch,\n        \"out_verify_offsets_scratch\",\n        (\n            (req_pool_indices, \"req_pool_indices\"),","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/kv_canary/plan/offsets_kernel.py#L187-L223","documentation":"The write-offsets array is a prefix-sum layout: it must hold exactly write_req_capacity + 1 int64 entries (one leading zero plus one offset per possible request). Any other length breaks the kernel's scatter/gather indexing.","triggerScenarios":"Calling launch_plan_offsets_kernel where write_offsets_len != write_req_capacity + 1 — classically allocating write_offsets with write_req_capacity elements.","commonSituations":"Off-by-one when allocating the offsets buffer; reusing a buffer sized for a different pool capacity after resizing.","solutions":["Allocate write_offsets = torch.empty(write_req_capacity + 1, dtype=torch.int64, device=dev) and pass write_offsets_len = write_req_capacity + 1","Add an assertion at allocation time to keep the invariant explicit"],"exampleFix":"// before\nwrite_offsets = torch.zeros(write_req_capacity, dtype=torch.int64, device=dev)\nlaunch_plan_offsets_kernel(..., write_offsets_len=write_offsets.shape[0], ...)\n// after\nwrite_offsets = torch.zeros(write_req_capacity + 1, dtype=torch.int64, device=dev)\nlaunch_plan_offsets_kernel(..., write_offsets_len=write_offsets.shape[0], ...)","handlingStrategy":"validation","validationCode":"assert write_offsets_len == write_req_capacity + 1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember the prefix-sum layout: offsets buffer is capacity+1"],"tags":["kv-canary","offsets","off-by-one"],"backgroundTag":"off-by-one-buffer-size","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}