{"record":{"id":"90d572fa6846fea6","repo":"sgl-project/sglang","slug":"actions-must-be-a-list-list-str","errorCode":null,"errorMessage":"actions must be a list[list[str]]","messagePattern":"actions must be a list\\[list\\[str\\]\\]","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/configs/pipeline_configs/lingbot_world.py","lineNumber":68,"sourceCode":"\n    def reset_camera_actions(self):\n        self.action_history.clear()\n        self.last_actions = []\n\n    def append_camera_actions(self, camera_actions: list[list[str]]) -> None:\n        for actions in camera_actions:\n            normalized = list(actions)\n            self.action_history.append(normalized)\n            self.last_actions = normalized\n\n    def dispose(self):\n        super().dispose()\n        self.reset_camera_actions()\n\n\ndef _validate_actions(actions: Any) -> list[list[str]]:\n    if not isinstance(actions, list):\n        raise TypeError(\"actions must be a list[list[str]]\")\n    result: list[list[str]] = []\n    for frame_actions in actions:\n        if not isinstance(frame_actions, list):\n            raise TypeError(\"actions must be a list[list[str]]\")\n        result.append(list(frame_actions))\n    return result\n\n\ndef _pad_actions_to_chunk(\n    action_history: list[list[str]], chunk_size: int\n) -> list[list[str]]:\n    if len(action_history) >= chunk_size:\n        return action_history\n    fill_item = action_history[-1] if action_history else []\n    return action_history + [\n        list(fill_item) for _ in range(chunk_size - len(action_history))\n    ]\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/configs/pipeline_configs/lingbot_world.py#L50-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nactions = \"move_forward\"  # or (\"move_forward\",)\n\n# after\nactions = [[\"move_forward\"]]","handlingStrategy":"type-guard","validationCode":"if not isinstance(actions, list):\n    actions = [[str(a)] for a in actions] if actions else []","typeGuard":"def is_valid_actions(a) -> bool:\n    return isinstance(a, list) and all(isinstance(f, list) and all(isinstance(s, str) for s in f) for f in a)","tryCatchPattern":"except TypeError as e:\n    if \"list[list[str]]\" in str(e):\n        actions = [[a] for a in actions] if isinstance(actions, (list, tuple)) else []\n        retry(actions)","preventionTips":["Always construct actions as [[...] per frame]","Normalize JSON/YAML-loaded structures to lists before the call","Unit-test the actions builder for shape"],"tags":["sglang","lingbot-world","type-validation","actions","embodied-ai"],"backgroundTag":"argument-type-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}