sgl-project/sglang · error · ValueError
Every extra_key should be a string.
Error message
Every extra_key should be a string.
What it means
Raised when normalizing batched GenerateReqInput where extra_key is a list but at least one element is not a str. extra_key is the radix-cache attention identity key, and SGLang requires each per-request key to be a string (empty strings are treated as None, i.e. no key).
Source
Thrown at python/sglang/srt/managers/io_struct.py:793
elif self.parallel_sample_num > 1:
raise ValueError(
"Cannot use list custom_logit_processor with parallel_sample_num > 1"
)
def _normalize_extra_key(self, num):
"""Normalize extra_key for batch processing."""
if self.extra_key is None:
return
if isinstance(self.extra_key, str):
value = self.extra_key or None
self.extra_key = [value] * num
elif isinstance(self.extra_key, list):
if len(self.extra_key) != self.batch_size:
raise ValueError(
"The length of extra_key should be equal to the batch size."
)
if any(not isinstance(value, str) for value in self.extra_key):
raise ValueError("Every extra_key should be a string.")
self.extra_key = [value or None for value in self.extra_key]
self.extra_key = self.extra_key * self.parallel_sample_num
else:
raise ValueError("extra_key should be a list or a string.")
def _normalize_cache_salt(self, num):
"""Normalize cache_salt for batch processing."""
if self.cache_salt is None:
return
if isinstance(self.cache_salt, str):
value = self.cache_salt or None
self.cache_salt = [value] * num
elif isinstance(self.cache_salt, list):
if len(self.cache_salt) != self.batch_size:
raise ValueError(
"The length of cache_salt should be equal to the batch size."
)
if any(not isinstance(value, str) for value in self.cache_salt):View on GitHub (pinned to 0132848349)
Solutions
- Convert every element to str: extra_key=[str(k) for k in keys]
- Use empty string '' (becomes None) for requests that need no cache key
- Pass extra_key as a single str to apply to the whole batch
Example fix
// before req = GenerateReqInput(text=['a','b'], extra_key=[1234, 5678]) // after req = GenerateReqInput(text=['a','b'], extra_key=['1234','5678'])
Defensive patterns
Strategy: validation
Validate before calling
assert isinstance(extra_key, list) and len(extra_key) == batch_size assert all(isinstance(k, str) for k in extra_key)
Type guard
def is_valid_extra_key(k, n) -> bool:
return isinstance(k, str) or (isinstance(k, list) and len(k) == n and all(isinstance(x, str) for x in k)) Prevention
- Always build extra_key as list[str] with len == batch_size
- Hash to hex strings, never bytes or ints
When it happens
Trigger: Calling the generate/batch API with extra_key=[123, 'abc'] or [None, 'k'] where batch_size=2; passing numpy/python objects instead of str.
Common situations: Building extra_key from hashes or ints (e.g. md5 digest as bytes, or numeric IDs) instead of str; mixing None into the list.
Related errors
- extra_key should be a list or a string.
- The length of cache_salt should be equal to the batch size.
- lora_path list length ({len(self.lora_path)}) must match bat
- Krea-2 sequence parallelism does not support ragged/padded m
- refiner cu_seqlens live text length must be in [1, {int(prom
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/50c64c795b2ff16c.
Report an issue: GitHub.