sgl-project/sglang · error · ValueError

kv-canary: lut_len must be positive when has_swa_lut is True

Error message

kv-canary: lut_len must be positive when has_swa_lut is True

What it means

When the SWA LUT specialization is enabled the kernel actually reads the LUT, so lut_len must be at least 1; a zero-length LUT with has_swa_lut=True means the kernel would read out of bounds.

Source

Thrown at python/sglang/kernels/ops/kv_canary/plan/offsets_kernel.py:179

        raise ValueError(
            f"kv-canary: write_req_capacity must be non-negative, got {write_req_capacity}"
        )
    if verify_capacity < 0:
        raise ValueError(
            f"kv-canary: verify_capacity must be non-negative, got {verify_capacity}"
        )
    if req_to_token_stride0 <= 0:
        raise ValueError(
            f"kv-canary: req_to_token_stride0 must be positive, got {req_to_token_stride0}"
        )
    if lut_len < 0:
        raise ValueError(f"kv-canary: lut_len must be non-negative, got {lut_len}")
    if not isinstance(has_swa_lut, bool):
        raise ValueError(
            f"kv-canary: has_swa_lut must be bool, got {type(has_swa_lut).__name__}"
        )
    if has_swa_lut and lut_len <= 0:
        raise ValueError("kv-canary: lut_len must be positive when has_swa_lut is True")
    if not has_swa_lut and lut_len != 0:
        raise ValueError("kv-canary: lut_len must be 0 when has_swa_lut is False")

    _require_len(req_pool_indices, "req_pool_indices", bs)
    _require_len(prefix_lens, "prefix_lens", bs)
    _require_len(extend_seq_lens, "extend_seq_lens", bs)
    _require_2d(req_to_token, "req_to_token")
    _require_min_len(lut_tensor, "lut_tensor", max(lut_len, 1))
    _require_min_len(
        out_verify_offsets_scratch,
        "out_verify_offsets_scratch",
        _PLAN_BS_BLOCK_SIZE + 1,
    )
    _require_len(out_write_offsets, "out_write_offsets", write_offsets_len)
    _require_len(
        out_write_seed_slot_indices,
        "out_write_seed_slot_indices",
        write_req_capacity,

View on GitHub (pinned to 0132848349)

Solutions

  1. Populate the full-to-SWA LUT before launching and pass its real length
  2. Or set has_swa_lut=False and lut_len=0 if SWA translation genuinely isn't needed

Example fix

// before
launch_plan_offsets_kernel(..., lut_tensor=torch.zeros(0, dtype=torch.int64), lut_len=0, has_swa_lut=True)
// after
launch_plan_offsets_kernel(..., lut_tensor=full_to_swa_lut, lut_len=int(full_to_swa_lut.shape[0]), has_swa_lut=True)
Defensive patterns

Strategy: validation

Validate before calling

if has_swa_lut:
    assert lut_len >= 1 and int(lut_tensor.shape[0]) >= lut_len

Prevention

When it happens

Trigger: Calling launch_plan_offsets_kernel with has_swa_lut=True but lut_len == 0 (empty LUT tensor) while swa_window_size implies SWA translation is needed.

Common situations: SWA mapping tensor allocated empty because the SWA pool was never populated; wiring has_swa_lut from a different flag than the LUT itself.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/7b6e8478f059a4ff. Report an issue: GitHub.