{"record":{"id":"00da68969d408fef","repo":"sgl-project/sglang","slug":"kv-canary-launch-canary-plan-kernels-requires-ful","errorCode":null,"errorMessage":"kv-canary: launch_canary_plan_kernels requires full_to_swa_index_mapping when swa_window_size > 0","messagePattern":"kv-canary: launch_canary_plan_kernels requires full_to_swa_index_mapping when swa_window_size > 0","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/kv_canary/plan/api.py","lineNumber":116,"sourceCode":"\n    Calling contract:\n        - Pure side-effect; no host work, no D2H.\n        - Safe in cuda-graph capture; caller refills all input tensors in-place before replay.\n        - The wrapper launches the plan sub-kernels needed to fill both plans end-to-end.\n        - Padding rows contribute zero entries.\n\n    Pinned by Python reference\n    :func:`sglang.kernels.ops.kv_canary.plan_ref.launch_canary_plan_kernels_torch_reference`; both the Triton\n    offsets kernel and the CUDA JIT entries kernel must match byte-for-byte.\n    \"\"\"\n    bs = int(req_pool_indices.shape[0])\n    if bs > _PLAN_BS_BLOCK_SIZE:\n        raise ValueError(\n            f\"kv-canary: launch_canary_plan_kernels supports at most bs={_PLAN_BS_BLOCK_SIZE} reqs per launch, \"\n            f\"got bs={bs}. Bump _PLAN_BS_BLOCK_SIZE if real workloads need this.\"\n        )\n    if swa_window_size > 0 and full_to_swa_index_mapping is None:\n        raise ValueError(\n            \"kv-canary: launch_canary_plan_kernels requires full_to_swa_index_mapping when swa_window_size > 0\"\n        )\n\n    device = verify_plan_out.verify_slot_indices.device\n    verify_offsets_scratch = torch.empty(\n        _PLAN_BS_BLOCK_SIZE + 1, dtype=torch.int64, device=device\n    )\n\n    plan_verify_capacity = int(verify_plan_out.verify_slot_indices.shape[0])\n    if verify_capacity != plan_verify_capacity:\n        raise ValueError(\n            f\"kv-canary: launch_canary_plan_kernels verify_capacity={verify_capacity} does not match \"\n            f\"verify_plan_out.verify_slot_indices.shape[0]={plan_verify_capacity}\"\n        )\n\n    write_plan_out.write_offsets.zero_()\n\n    launch_plan_offsets_kernel(","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/kv_canary/plan/api.py#L98-L134","documentation":"The kv-canary plan launcher requires a full-to-SWA index mapping (LUT) whenever a positive sliding-window size is given, because the SWA path needs the mapping to translate full KV indices into SWA-pool indices. Omitting it would make the kernel unable to compute SWA offsets safely, so it fails fast with a ValueError.","triggerScenarios":"Calling launch_canary_plan_kernels (directly or via invoke_plan/_run_both_plan) with swa_window_size > 0 but full_to_swa_index_mapping=None.","commonSituations":"Running a hybrid SWA model (e.g. Gemma-2/3-style sliding window) where the caller wired swa_window_size from the attention backend but forgot to pass the mapping tensor built by the memory pool/token allocator.","solutions":["Pass the full_to_swa_index_mapping tensor produced by your SWA/hybrid KV allocator when swa_window_size > 0","If your model has no SWA layers, pass swa_window_size=0 so no mapping is required","Check the caller (invoke_plan/_run_both_plan) to confirm the mapping is forwarded from the memory pool config"],"exampleFix":"// before\nlaunch_canary_plan_kernels(..., swa_window_size=window, full_to_swa_index_mapping=None)\n// after\nlaunch_canary_plan_kernels(..., swa_window_size=window, full_to_swa_index_mapping=full_to_swa_lut)","handlingStrategy":"validation","validationCode":"if swa_window_size > 0:\n    assert full_to_swa_index_mapping is not None, \"SWA window requires full_to_swa_index_mapping\"","typeGuard":"def has_swa_mapping(swa_window_size: int, lut: torch.Tensor | None) -> bool:\n    return swa_window_size <= 0 or lut is not None","tryCatchPattern":null,"preventionTips":["Build and pass the SWA LUT whenever the model config declares sliding-window layers","Add an assert at plan-setup time tying swa_window_size to LUT presence"],"tags":["kv-canary","sliding-window","argument-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}