sgl-project/sglang · error · TypeError
actions must be a list[list[str]]
Error message
actions must be a list[list[str]]
What it means
The Lingbot World pipeline validates that the per-frame 'actions' argument is a list of lists of strings (one inner list of action names per frame). This TypeError is thrown when the top-level actions value is not a Python list at all — e.g. a string, tuple, numpy array, or None.
Source
Thrown at python/sglang/multimodal_gen/configs/pipeline_configs/lingbot_world.py:68
def reset_camera_actions(self):
self.action_history.clear()
self.last_actions = []
def append_camera_actions(self, camera_actions: list[list[str]]) -> None:
for actions in camera_actions:
normalized = list(actions)
self.action_history.append(normalized)
self.last_actions = normalized
def dispose(self):
super().dispose()
self.reset_camera_actions()
def _validate_actions(actions: Any) -> list[list[str]]:
if not isinstance(actions, list):
raise TypeError("actions must be a list[list[str]]")
result: list[list[str]] = []
for frame_actions in actions:
if not isinstance(frame_actions, list):
raise TypeError("actions must be a list[list[str]]")
result.append(list(frame_actions))
return result
def _pad_actions_to_chunk(
action_history: list[list[str]], chunk_size: int
) -> list[list[str]]:
if len(action_history) >= chunk_size:
return action_history
fill_item = action_history[-1] if action_history else []
return action_history + [
list(fill_item) for _ in range(chunk_size - len(action_history))
]
View on GitHub (pinned to 0132848349)
Solutions
- Pass actions as a list of lists of strings: [["move_forward"], ["turn_left", "move_forward"]]
- If you have one frame, wrap it: actions=[["move_forward"]] not actions="move_forward"
- Convert tuples/arrays to lists before the call: actions=[list(f) for f in actions]
- Add a None check / default before calling if actions may be absent
Example fix
# before
actions = "move_forward" # or ("move_forward",)
# after
actions = [["move_forward"]] Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(actions, list):
actions = [[str(a)] for a in actions] if actions else [] Type guard
def is_valid_actions(a) -> bool:
return isinstance(a, list) and all(isinstance(f, list) and all(isinstance(s, str) for s in f) for f in a) Try / catch
except TypeError as e:
if "list[list[str]]" in str(e):
actions = [[a] for a in actions] if isinstance(actions, (list, tuple)) else []
retry(actions) Prevention
- Always construct actions as [[...] per frame]
- Normalize JSON/YAML-loaded structures to lists before the call
- Unit-test the actions builder for shape
When it happens
Trigger: Calling generation with actions not being a list, e.g. actions="move_forward" (a plain string), actions=("move","turn") (tuple), actions=None, or a numpy array — _validate_actions fails the outer isinstance(actions, list) check before any frame is inspected.
Common situations: Passing a single action string directly instead of wrapping it; deserializing actions from JSON/YAML into a tuple or array; forgetting the actions argument's nested structure (frames × actions) when porting an example.
Related errors
- Inkling reasoning_effort must not be a boolean
- cuda-graph mode cu_seqlens should be a list
- flashinfer_cudnn expects packed indptrs as a torch.Tensor
- Invalid combination of query/items types for score_request.
- Invalid type for item in --lora-paths list: {type(lora_path)
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/90d572fa6846fea6.
Report an issue: GitHub.