{"record":{"id":"dca18f3c0490ace0","repo":"FoundationAgents/OpenManus","slug":"a-plan-with-id-plan-id-already-exists-use-up","errorCode":null,"errorMessage":"A plan with ID '{plan_id}' already exists. Use 'update' to modify existing plans.","messagePattern":"A plan with ID '(.+?)' already exists\\. Use 'update' to modify existing plans\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"warning","filePath":"app/tool/planning.py","lineNumber":128,"sourceCode":"            return self._set_active_plan(plan_id)\n        elif command == \"mark_step\":\n            return self._mark_step(plan_id, step_index, step_status, step_notes)\n        elif command == \"delete\":\n            return self._delete_plan(plan_id)\n        else:\n            raise ToolError(\n                f\"Unrecognized command: {command}. Allowed commands are: create, update, list, get, set_active, mark_step, delete\"\n            )\n\n    def _create_plan(\n        self, plan_id: Optional[str], title: Optional[str], steps: Optional[List[str]]\n    ) -> 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,","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/FoundationAgents/OpenManus/blob/52a13f2a57d8c7f6737eefb02ccf569594d44273/app/tool/planning.py#L110-L146","documentation":"Raised by _create_plan (app/tool/planning.py:128) when creating a plan whose plan_id already exists in the in-memory store self.plans. Creation is intentionally non-destructive: the tool refuses to overwrite and points you at the update command instead. Note plans are process-memory only (class-level dict), so IDs persist across calls within the same process/session.","triggerScenarios":"Calling command='create' twice with the same plan_id; re-running a create after a previous successful create in the same process; plan IDs reused across agent turns (e.g. always 'main') while the process is still alive.","commonSituations":"Agent retry loops that re-issue the create after a partially failed later step; prompts that hardcode a plan_id like 'current'; class-level mutable state (plans: dict = {}) shared across instances, making collisions appear even between separate tool instances in one process.","solutions":["If you intend to modify the existing plan, use command='update' with the same plan_id.","If you want a fresh plan, either delete first (command='delete') or use a unique plan_id (timestamp/uuid suffix).","Check existence before creating: call command='list' and compare IDs, or maintain the set of used IDs in the caller."],"exampleFix":"// before\nawait planning.execute(command='create', plan_id='main', title='T', steps=['a'])  # second time -> ToolError\n\n// after\nif 'main' in used_ids:\n    await planning.execute(command='update', plan_id='main', title='T', steps=['a'])\nelse:\n    await planning.execute(command='create', plan_id='main', title='T', steps=['a'])","handlingStrategy":"validation","validationCode":"existing = {p.split(':')[0] for p in (await planning.execute(command='list')).output.splitlines()}\n# simpler: track ids you created in this session\nif plan_id in created_ids:\n    await planning.execute(command='update', plan_id=plan_id, title=title, steps=steps)\nelse:\n    created_ids.add(plan_id)\n    await planning.execute(command='create', plan_id=plan_id, title=title, steps=steps)","typeGuard":null,"tryCatchPattern":"try:\n    await planning.execute(command='create', plan_id=pid, title=t, steps=s)\nexcept ToolError as e:\n    if 'already exists' in str(e):\n        await planning.execute(command='update', plan_id=pid, title=t, steps=s)\n    else:\n        raise","preventionTips":["Make retries idempotent: on ambiguous create failures, list plans before re-issuing create.","Use unique IDs per logical plan (title-slug + short uuid) instead of constants like 'main'.","Remember plans live in process memory — restarts reset collisions, workers diverge."],"tags":["planning","duplicate","validation"],"backgroundTag":null,"analyzedSha":"52a13f2a57d8c7f6737eefb02ccf569594d44273","analyzedAt":"2026-08-15T02:33:49.993Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}