{"record":{"id":"589a2d937bf8a538","repo":"sgl-project/sglang","slug":"kv-canary-name-length-must-be-minimum-got","errorCode":null,"errorMessage":"kv-canary: {name} length must be >= {minimum}, got {actual}","messagePattern":"kv-canary: (.+?) length must be >= (.+?), got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/kv_canary/plan/utils.py","lineNumber":57,"sourceCode":"def _require_2d(tensor: torch.Tensor, name: str) -> None:\n    if tensor.ndim != 2:\n        raise ValueError(\n            f\"kv-canary: {name} must be 2-D, got shape {tuple(tensor.shape)}\"\n        )\n\n\ndef _require_len(tensor: torch.Tensor, name: str, expected: int) -> None:\n    _require_1d(tensor=tensor, name=name)\n    actual = int(tensor.shape[0])\n    if actual != expected:\n        raise ValueError(f\"kv-canary: {name} length must be {expected}, got {actual}\")\n\n\ndef _require_min_len(tensor: torch.Tensor, name: str, minimum: int) -> None:\n    _require_1d(tensor=tensor, name=name)\n    actual = int(tensor.shape[0])\n    if actual < minimum:\n        raise ValueError(f\"kv-canary: {name} length must be >= {minimum}, got {actual}\")\n\n\ndef _require_same_device(\n    reference: torch.Tensor,\n    reference_name: str,\n    tensors: tuple[tuple[torch.Tensor, str], ...],\n) -> None:\n    for tensor, name in tensors:\n        if tensor.device != reference.device:\n            raise ValueError(\n                f\"kv-canary: {name} must be on {reference_name}'s device \"\n                f\"{reference.device}, got {tensor.device}\"\n            )\n\n\n@triton.jit\ndef _compute_window_start(prefix_lens, SWA_WINDOW: tl.constexpr):\n    \"\"\"Per-req window start: max(prefix_lens - SWA_WINDOW, 0) when SWA, else 0.","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/kv_canary/plan/utils.py#L39-L75","documentation":"Some inputs (like the LUT) only need a minimum length rather than an exact one; this error fires when such a tensor is shorter than the required minimum, meaning the kernel could read past its end.","triggerScenarios":"Calling launch_plan_offsets_kernel where lut_tensor (or another min-length-checked input) has shape[0] below the declared lut_len minimum — e.g. lut_len set larger than the actual LUT tensor.","commonSituations":"lut_len taken from config (max index + 1) while the allocated LUT is smaller; LUT truncated after a pool resize.","solutions":["Grow the LUT tensor to at least lut_len elements","Or correct lut_len to the tensor's real length when the config value is stale"],"exampleFix":"// before\nlut_len = max_token_id + 1\nlut_tensor = torch.zeros(max_token_id, dtype=torch.int64, device=dev)\n// after\nlut_len = max_token_id + 1\nlut_tensor = torch.zeros(lut_len, dtype=torch.int64, device=dev)","handlingStrategy":"validation","validationCode":"assert lut_tensor.shape[0] >= max(lut_len, 1)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Allocate the LUT with exactly lut_len elements and keep them in sync"],"tags":["kv-canary","length-mismatch","lut"],"backgroundTag":"tensor-length-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}