{"record":{"id":"4cc8b0f1e8840bc4","repo":"FoundationAgents/OpenManus","slug":"no-plan-found-with-id-plan-id","errorCode":null,"errorMessage":"No plan found with ID: {plan_id}","messagePattern":"No plan found with ID: (.+?)","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"warning","filePath":"app/tool/planning.py","lineNumber":168,"sourceCode":"            \"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        )\n\n    def _update_plan(\n        self, plan_id: Optional[str], title: Optional[str], steps: Optional[List[str]]\n    ) -> ToolResult:\n        \"\"\"Update an existing plan with new title or steps.\"\"\"\n        if not plan_id:\n            raise ToolError(\"Parameter `plan_id` is required for command: update\")\n\n        if plan_id not in self.plans:\n            raise ToolError(f\"No plan found with ID: {plan_id}\")\n\n        plan = self.plans[plan_id]\n\n        if title:\n            plan[\"title\"] = title\n\n        if steps:\n            if not isinstance(steps, list) or not all(\n                isinstance(step, str) for step in steps\n            ):\n                raise ToolError(\n                    \"Parameter `steps` must be a list of strings for command: update\"\n                )\n\n            # Preserve existing step statuses for unchanged steps\n            old_steps = plan[\"steps\"]\n            old_statuses = plan[\"step_statuses\"]\n            old_notes = plan[\"step_notes\"]","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/FoundationAgents/OpenManus/blob/52a13f2a57d8c7f6737eefb02ccf569594d44273/app/tool/planning.py#L150-L186","documentation":"Raised by _update_plan (app/tool/planning.py:168) when command='update' targets a plan_id not present in the in-memory self.plans dict. The store is process-local (class-level dict), so IDs created in a previous process run or a different worker do not exist here. Checked before any mutation.","triggerScenarios":"Calling update with a typo'd or stale plan_id; updating after the plan was deleted (command='delete'); updating in a new process/session that never created the plan (no persistence between restarts).","commonSituations":"Agent sessions resumed after a process restart expecting plans to persist; horizontal scaling where each worker has its own class-level dict; ID casing/whitespace mismatches ('Plan1' vs 'plan1').","solutions":["Run command='list' first and use an exact existing plan_id.","If the plan is genuinely gone (restart/delete), recreate it with command='create' (rebuilding step statuses to not_started).","If persistence matters, serialize plans outside the tool and replay creates on startup — the tool has no built-in storage.","Normalize IDs at the caller (strip/consistent casing) to avoid mismatch collisions."],"exampleFix":"// before\nawait planning.execute(command='update', plan_id='release-2', title='T')  # typo, never created\n\n// after\nplans = await planning.execute(command='list')\n# pick exact id from output, then:\nawait planning.execute(command='update', plan_id='release-1', title='T')","handlingStrategy":"validation","validationCode":"ids = await list_plan_ids(planning)  # via command='list'\nif plan_id not in ids:\n    raise KeyError(f'plan {plan_id!r} not found; existing: {sorted(ids)}')\nawait planning.execute(command='update', plan_id=plan_id, title=title)","typeGuard":null,"tryCatchPattern":"try:\n    await planning.execute(command='update', plan_id=pid, title=t)\nexcept ToolError as e:\n    if 'No plan found' in str(e):\n        await planning.execute(command='create', plan_id=pid, title=t, steps=fallback_steps)\n    else:\n        raise","preventionTips":["Keep the set of live plan IDs in caller state and validate before update.","Recreate plans on process restart if your flow depends on them — the store is in-memory.","Normalize IDs (strip, consistent casing) wherever they are produced or consumed."],"tags":["planning","not-found","in-memory-state"],"backgroundTag":null,"analyzedSha":"52a13f2a57d8c7f6737eefb02ccf569594d44273","analyzedAt":"2026-08-15T02:33:49.993Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}