{"record":{"id":"74b5fb2e58515d5c","repo":"FoundationAgents/OpenManus","slug":"parameter-steps-must-be-a-non-empty-list-of-stri","errorCode":null,"errorMessage":"Parameter `steps` must be a non-empty list of strings for command: create","messagePattern":"Parameter `steps` must be a non-empty list of strings for command: create","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"warning","filePath":"app/tool/planning.py","lineNumber":140,"sourceCode":"    ) -> ToolResult:\n        \"\"\"Create a new plan with the given ID, title, and steps.\"\"\"\n        if not plan_id:\n            raise ToolError(\"Parameter `plan_id` is required for command: create\")\n\n        if plan_id in self.plans:\n            raise ToolError(\n                f\"A plan with ID '{plan_id}' already exists. Use 'update' to modify existing plans.\"\n            )\n\n        if not title:\n            raise ToolError(\"Parameter `title` is required for command: create\")\n\n        if (\n            not steps\n            or not isinstance(steps, list)\n            or not all(isinstance(step, str) for step in steps)\n        ):\n            raise ToolError(\n                \"Parameter `steps` must be a non-empty list of strings for command: create\"\n            )\n\n        # Create a new plan with initialized step statuses\n        plan = {\n            \"plan_id\": plan_id,\n            \"title\": title,\n            \"steps\": steps,\n            \"step_statuses\": [\"not_started\"] * len(steps),\n            \"step_notes\": [\"\"] * len(steps),\n        }\n\n        self.plans[plan_id] = plan\n        self._current_plan_id = plan_id  # Set as active plan\n\n        return ToolResult(\n            output=f\"Plan created successfully with ID: {plan_id}\\n\\n{self._format_plan(plan)}\"\n        )","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/FoundationAgents/OpenManus/blob/52a13f2a57d8c7f6737eefb02ccf569594d44273/app/tool/planning.py#L122-L158","documentation":"Raised by _create_plan (app/tool/planning.py:140) when the steps argument for command='create' is None, an empty list, or not a list of strings (any non-str element fails the all() check). Steps drive step_statuses/step_notes arrays ('not_started' * len(steps)), so at least one string step is mandatory at creation.","triggerScenarios":"Calling create with steps omitted, steps=[], steps='step one' (a plain string, not a list), or steps=['a', 2] (mixed types). JSON configs that pass a dict or nested arrays also fail the isinstance checks.","commonSituations":"LLM tool calls that summarize steps as one string instead of a list; empty plans attempted as placeholders; steps parsed from YAML/JSON landing as tuples or dicts before reaching the tool.","solutions":["Pass a non-empty list of strings: steps=['Install deps', 'Run tests', 'Deploy'].","If the model returned a single string, wrap/split it: steps=[s.strip() for s in raw.split('\\n') if s.strip()].","If you genuinely need an empty plan, create it with one placeholder step ('Define steps') and later update with the real list."],"exampleFix":"// before\nawait planning.execute(command='create', plan_id='p1', title='T', steps='do things')\n\n// after\nawait planning.execute(command='create', plan_id='p1', title='T', steps=['do things'])","handlingStrategy":"validation","validationCode":"if not isinstance(steps, list) or not steps or not all(isinstance(s, str) and s.strip() for s in steps):\n    raise ValueError('steps must be a non-empty list[str]')\nawait planning.execute(command='create', plan_id=pid, title=title, steps=steps)","typeGuard":"from typing import TypeGuard\ndef is_step_list(v: object) -> TypeGuard[list[str]]:\n    return isinstance(v, list) and len(v) > 0 and all(isinstance(s, str) for s in v)","tryCatchPattern":"try:\n    await planning.execute(command='create', plan_id=pid, title=t, steps=s)\nexcept ToolError as e:\n    if 'steps` must be a non-empty list' in str(e):\n        s = [str(x).strip() for x in s if str(x).strip()] or ['Placeholder step']\n        await planning.execute(command='create', plan_id=pid, title=t, steps=s)\n    else:\n        raise","preventionTips":["Coerce model output: wrap single strings or split newline-delimited text into list[str].","Validate with a TypeGuard before the call to keep the error out of the agent loop.","Never pass tuples/dicts — the tool requires a real list of str."],"tags":["planning","validation","type-error"],"backgroundTag":null,"analyzedSha":"52a13f2a57d8c7f6737eefb02ccf569594d44273","analyzedAt":"2026-08-15T02:33:49.993Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}