sgl-project/sglang · error · ValueError
All ranges must be within [0, {max_seqlen}], got {range_valu
Error message
All ranges must be within [0, {max_seqlen}], got {range_values} What it means
This error is raised by build_varlen_mask_meta_from_ranges when building varlen attention mask metadata from per-row (start, end) range pairs. Every range must satisfy 0 <= start <= end <= max_seqlen for every row in range_values; otherwise the varlen layout would be invalid and kernels would read out of bounds or produce garbage.
Source
Thrown at python/sglang/multimodal_gen/runtime/layers/attention/layer.py:218
device: torch.device,
) -> dict:
"""Build varlen FA metadata from host-side valid token ranges.
``valid_ranges[i]`` contains half-open intervals in row-local coordinates.
The intervals are packed in the provided order, matching the flattened
``nonzero`` order for ordinary left-to-right masks.
"""
range_values = [
[(int(start), int(end)) for start, end in row_ranges]
for row_ranges in valid_ranges
]
if any(
start < 0 or end < start or end > max_seqlen
for row_ranges in range_values
for start, end in row_ranges
):
raise ValueError(
f"All ranges must be within [0, {max_seqlen}], got {range_values}"
)
bs = len(range_values)
length_values = [
sum(end - start for start, end in row_ranges) for row_ranges in range_values
]
valid_lens = torch.as_tensor(length_values, dtype=torch.int32, device=device)
cu_seqlens = torch.zeros(bs + 1, dtype=torch.int32, device=device)
cu_seqlens[1:] = torch.cumsum(valid_lens, dim=0)
index_parts = [
torch.arange(
row * max_seqlen + start,
row * max_seqlen + end,
dtype=torch.long,
device=device,
)View on GitHub (pinned to 0132848349)
Solutions
- Recompute the ranges: verify each row's ranges are sorted, non-overlapping, and that sum(end-start) equals the row's actual token count
- Check that max_seqlen passed in matches the padded/total sequence length the ranges were computed against (especially under SP, use the global length, not the shard-local one)
- Debug-print range_values and max_seqlen right before the call to find the offending row: [ (s,e) for row in range_values for s,e in row if s<0 or e<s or e>max_seqlen ]
- If ranges come from a previous stage, fix the cumulative offset computation upstream (e.g. text prefix length + image segment offsets)
Example fix
// before
meta = build_varlen_mask_meta_from_ranges(ranges, max_seqlen=local_max)
// after
assert all(0 <= s <= e <= max_seqlen for row in ranges for s, e in row), f"bad ranges {ranges} vs max {max_seqlen}"
meta = build_varlen_mask_meta_from_ranges(ranges, max_seqlen=max_seqlen) Defensive patterns
Strategy: validation
Validate before calling
def ranges_ok(range_values, max_seqlen):
return all(0 <= s <= e <= max_seqlen for row in range_values for s, e in row)
if not ranges_ok(ranges, max_seqlen):
bad = [(s, e) for row in ranges for s, e in row if s < 0 or e < s or e > max_seqlen]
raise ValueError(f"invalid ranges {bad} for max_seqlen={max_seqlen}") Type guard
def is_valid_ranges(rv: list[list[tuple[int, int]]], m: int) -> bool:
return all(isinstance(s, int) and isinstance(e, int) and 0 <= s <= e <= m
for row in rv for s, e in row) Prevention
- Always derive ranges from the same cumulative-length array used to compute max_seqlen
- Assert range invariants in test fixtures (see test_prefix_text_plus_full_image_matches_nonzero_builder)
- Under sequence parallelism, validate against the global sequence length, not the shard-local one
When it happens
Trigger: Calling build_varlen_mask_meta_from_ranges (directly or via build_varlen_mask_meta_from_lengths, the attention layer's forward, or _get_joint_attn_mask_and_meta) with range_values where some start < 0, end < start, or end > max_seqlen. Typically happens when token position offsets for an image/video segment exceed the actual sequence length, or when cumulative prefix lengths are miscomputed.
Common situations: Mixture-of-text-and-image batching where the prefix text length plus image token length exceeds max_seqlen; off-by-one in cumulative sum of seq lens; passing ranges indexed against a different (local vs global) sequence length under sequence parallelism; negative start after slicing with a bad offset.
Related errors
- The batch size is expected to be 1 rather than {q.shape[0]}
- hd256 forward varlen expects q rank 3 or 5, got rank {q_rank
- mask_search_files_path_pos, mask_search_files_path_neg, and
- {name} is required for NPU packed attention
- K/V-gather SP does not support varlen UlyssesAttention.
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/1306804cee0c752c.
Report an issue: GitHub.