sgl-project/sglang · error · ValueError
{name}_block_cnt and {name}_block_idx must both be provided
Error message
{name}_block_cnt and {name}_block_idx must both be provided or both be None What it means
Block-sparsity metadata comes in pairs: {name}_block_cnt and {name}_block_idx. _check_and_expand_block enforces that both are provided together or both are None; supplying only one raises ValueError.
Source
Thrown at python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py:242
hint_clause = f" Hint: {resolved_hint}" if resolved_hint else ""
raise ValueError(
f"{tensor_name}{context_clause} with shape {tensor.shape} cannot be expanded to expected shape {expected_shape}."
f"{hint_clause}"
)
return tensor.expand(*expected_shape)
def _check_and_expand_block(
name: str,
cnt: torch.Tensor | None,
idx: torch.Tensor | None,
expected_count_shape: Tuple[int, ...],
expected_index_shape: Tuple[int, ...],
context: str | None,
hint: str | Callable[[], str] | None,
) -> Tuple[torch.Tensor | None, torch.Tensor | None]:
if (cnt is None) != (idx is None):
raise ValueError(
f"{name}_block_cnt and {name}_block_idx must both be provided or both be None"
)
if cnt is None or idx is None:
return None, None
if cnt.dtype != torch.int32 or idx.dtype != torch.int32:
raise ValueError(f"{name}_block tensors must have dtype torch.int32")
if cnt.device != idx.device:
raise ValueError(
f"{name}_block_cnt and {name}_block_idx must be on the same device"
)
if not cnt.is_cuda or not idx.is_cuda:
raise ValueError(f"{name}_block tensors must live on CUDA")
expanded_cnt = _expand_sparsity_tensor(
cnt, expected_count_shape, f"{name}_block_cnt", context, hint
)
# [Note] Allow Compact block sparse indices
# Allow the last dimension (n_blocks) of idx to be <= expected, since
# FA4 only accesses indices 0..cnt-1 per query tile. This enables compactView on GitHub (pinned to 0132848349)
Solutions
- Provide both tensors or neither
- Check call site: if cnt is not None: assert idx is not None
Example fix
# before res = normalize_block_sparse_tensors(topk_cnt, None, ...) # after res = normalize_block_sparse_tensors(topk_cnt, topk_idx, ...)
Defensive patterns
Strategy: validation
Validate before calling
assert (cnt is None) == (idx is None), 'cnt and idx must be provided together'
Type guard
def valid_block_pair(cnt, idx) -> bool:\n return (cnt is None) == (idx is None)
Prevention
- Keep cnt/idx as a single dataclass or tuple through the codebase
- Add a paired-argument assert at the public API entry
When it happens
Trigger: Calling normalize_block_sparse_tensors (or FA with block-sparse args) with e.g. topk_block_cnt set but topk_block_idx=None, or vice versa.
Common situations: Building only the count tensor and forgetting the index tensor; partial refactors of sparsity metadata plumbing; optional-arg defaults left None on one side.
Related errors
- Invalid attention metadata values.Sparsity should be in [0,
- {tensor_name}{context_clause} with shape {tensor.shape} cann
- {name}_block tensors must have dtype torch.int32
- {name}_block_cnt and {name}_block_idx must be on the same de
- {name}_block tensors must live on CUDA
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/b347f1aa7941016f.
Report an issue: GitHub.