FoundationAgents/OpenManus · warning · ToolError

Parameter `plan_id` is required for command: create

Error message

Parameter `plan_id` is required for command: create

What it means

Raised by _create_plan (app/tool/planning.py:125) when command='create' is dispatched without a truthy plan_id. plan_id is the dictionary key for the in-memory plan store (self.plans), so creation requires it up front. This is input validation before any state is touched.

Source

Thrown at app/tool/planning.py:125

        elif command == "get":
            return self._get_plan(plan_id)
        elif command == "set_active":
            return self._set_active_plan(plan_id)
        elif command == "mark_step":
            return self._mark_step(plan_id, step_index, step_status, step_notes)
        elif command == "delete":
            return self._delete_plan(plan_id)
        else:
            raise ToolError(
                f"Unrecognized command: {command}. Allowed commands are: create, update, list, get, set_active, mark_step, delete"
            )

    def _create_plan(
        self, plan_id: Optional[str], title: Optional[str], steps: Optional[List[str]]
    ) -> ToolResult:
        """Create a new plan with the given ID, title, and steps."""
        if not plan_id:
            raise ToolError("Parameter `plan_id` is required for command: create")

        if plan_id in self.plans:
            raise ToolError(
                f"A plan with ID '{plan_id}' already exists. Use 'update' to modify existing plans."
            )

        if not title:
            raise ToolError("Parameter `title` is required for command: create")

        if (
            not steps
            or not isinstance(steps, list)
            or not all(isinstance(step, str) for step in steps)
        ):
            raise ToolError(
                "Parameter `steps` must be a non-empty list of strings for command: create"
            )

View on GitHub (pinned to 52a13f2a57)

Solutions

  1. Pass an explicit plan_id: `await planning.execute(command='create', plan_id='release-1', title=..., steps=[...])`.
  2. In the calling layer, generate an ID when the model omits one (e.g. slugify(title) or uuid4 hex) before invoking the tool.
  3. If you control prompts, make plan_id explicitly required in the instructions/examples for the create command.

Example fix

// before
await planning.execute(command='create', title='Refactor', steps=['a','b'])

// after
plan_id = plan_id or slugify(title)
await planning.execute(command='create', plan_id=plan_id, title='Refactor', steps=['a','b'])
Defensive patterns

Strategy: validation

Validate before calling

if not plan_id or not plan_id.strip():
    raise ValueError('create requires a plan_id')
await planning.execute(command='create', plan_id=plan_id, title=title, steps=steps)

Type guard

def is_plan_id(v: str | None) -> bool:
    return isinstance(v, str) and bool(v.strip())

Try / catch

try:
    await planning.execute(command='create', title=t, steps=s)
except ToolError as e:
    if 'plan_id` is required' in str(e):
        await planning.execute(command='create', plan_id=slugify(t), title=t, steps=s)
    else:
        raise

Prevention

When it happens

Trigger: Calling `await planning.execute(command='create', title='t', steps=['a'])` with plan_id omitted or set to '' / None. Common with LLM callers that assume the tool auto-generates an ID.

Common situations: Model-issued tool calls that omit plan_id because the schema marks only 'command' as required; callers used to APIs that auto-assign IDs; empty string passed from a templating bug.

Related errors


AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15). Data as JSON: /api/errors/e177cb18fd2eb594. Report an issue: GitHub.