{"record":{"id":"63872d2966717096","repo":"sgl-project/sglang","slug":"invalid-debug-name-write-range-local-local-st","errorCode":null,"errorMessage":"Invalid {debug_name} write range: local=[{local_start_index}, {local_end_index}), global_end={global_end_index}, prev_local_end={local_end_index_prev}, kv_cache_size={kv_cache_size}, num_new_tokens={num_new_tokens}, current_start={current_chunk_start}, current_end={current_chunk_end}","messagePattern":"Invalid (.+?) write range: local=\\[(.+?), (.+?)\\), global_end=(.+?), prev_local_end=(.+?), kv_cache_size=(.+?), num_new_tokens=(.+?), current_start=(.+?), current_end=(.+?)","errorType":"error_code","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"python/sglang/multimodal_gen/runtime/layers/kvcache/causal_attention_cache.py","lineNumber":287,"sourceCode":"                if self._has_pinned_sink() and self.pinned_start >= sink_tokens:\n                    self.pinned_start -= num_evicted_tokens\n\n                # if we move the minimum number of tokens, the right bound of the append token would be aligned with end of the buffer\n                local_end_index = kv_cache_size\n            else:\n                # enough space, directly append new tokens after end of previous chunk\n                local_end_index = local_end_index_prev + appended_tokens\n            local_start_index = local_end_index - num_new_tokens\n            updated_local_end = local_end_index\n            # after filling in the proceeded new chunk, the global end aligns with the global end of the current chunk\n            updated_global_end = current_chunk_end\n\n        if (\n            local_start_index < 0\n            or local_end_index > kv_cache_size\n            or local_end_index - local_start_index != num_new_tokens\n        ):\n            raise RuntimeError(\n                f\"Invalid {debug_name} write range: \"\n                f\"local=[{local_start_index}, {local_end_index}), \"\n                f\"global_end={global_end_index}, \"\n                f\"prev_local_end={local_end_index_prev}, \"\n                f\"kv_cache_size={kv_cache_size}, \"\n                f\"num_new_tokens={num_new_tokens}, \"\n                f\"current_start={current_chunk_start}, current_end={current_chunk_end}\"\n            )\n\n        if self.k.requires_grad:\n            self.k = self.k.detach()\n        if self.v.requires_grad:\n            self.v = self.v.detach()\n        attn_start_index = max(0, updated_local_end - self.attention_window_size)\n\n        # write fresh kv and return visible view\n        if cache_head_slice is None:\n            self.k[:, local_start_index:local_end_index] = key","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/layers/kvcache/causal_attention_cache.py#L269-L305","documentation":"A RuntimeError from update_and_get_attention_kv asserting the computed local write window is sane: start >= 0, end <= kv_cache_size, and the window length equals num_new_tokens. It fires when chunk bookkeeping (global_end, previous local end, current_chunk_start/end) is inconsistent with the token count being written.","triggerScenarios":"Calling update_and_get_attention_kv where current_chunk_start is far from the previous global_end, or num_new_tokens exceeds kv_cache_size, or a rewind/rewrite produces a window length different from num_new_tokens.","commonSituations":"Non-sequential chunk starts after a rollback/replay in diffusion or realtime generation; kv_cache_size configured smaller than a single chunk; off-by-one in current_chunk_start tracking across denoise steps.","solutions":["Check the printed diagnostics: ensure current_chunk_start equals previous global_end for appends, and num_new_tokens <= kv_cache_size","Increase kv_cache_size to hold the largest chunk","Fix chunk-start bookkeeping in the caller (reset/rewind logic must keep indices consistent)"],"exampleFix":"# before\ncache.update_and_get_attention_kv(k, v, current_chunk_start=rewind_pos + 1, ...)\n# after\ncache.update_and_get_attention_kv(k, v, current_chunk_start=rewind_pos, ...)","handlingStrategy":"validation","validationCode":"assert current_chunk_start == cache.global_end or current_chunk_start == cache.cur_start, 'non-sequential chunk'\nassert num_new_tokens <= cache.kv_cache_size","typeGuard":null,"tryCatchPattern":"try:\\n    cache.update_and_get_attention_kv(k, v, current_chunk_start=s)\\nexcept RuntimeError as e:\\n    if 'Invalid' in str(e) and 'write range' in str(e):\\n        cache.reset(); cache.update_and_get_attention_kv(k, v, current_chunk_start=s)","preventionTips":["Track chunk positions centrally, not per-caller","Size kv_cache_size >= max chunk length","Add invariant asserts on window length == num_new_tokens before calling"],"tags":["kv-cache","index-out-of-range","assertion","chunking"],"backgroundTag":"kv-cache-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}