Skip to content

Bug: create_task MCP schema description advertises type/status enum values the validator rejects #263

@nicsuzor

Description

@nicsuzor

The create_task MCP tool's JSON Schema parameter descriptions advertise type and status enum values that the server's validator rejects at create time. Callers hit the documented values, get Invalid task type / Invalid status errors, and have to re-roll the request — usually downgrading to plain type: task and tagging the intended type instead. This causes loss of structural information about what kind of work each task represents.

Root Cause Analysis

Failure: create_task schema description advertises enum values for type and status that the server validator rejects.

Causal chain:

  1. Caller invokes create_task with type: bug (or feature). The tool's type parameter description says: "Task type (default: 'task'). Also accepts: epic, bug, feature, learn, goal, project."
  2. The validator should either accept the values listed in the schema description, or the description should list only what the validator accepts.
  3. Server responds: Failed to create task: Invalid task type: bug. Same with feature.
  4. Caller retries with type: task and status: active. The status parameter description says: "default: 'draft' — new tasks start as draft and are excluded from ready queue until promoted to 'active'. Also accepts: active, blocked, done, merge_ready, in_progress, etc." — strongly implying active is a valid status.
  5. Server responds: Failed to create task: Invalid status: active.
  6. Caller settles on type: task + status: ready (or in_progress), which work, and falls back to using tags (tags: ["bug"], tags: ["feature"]) to preserve the type signal that should have lived in the type field.

Root cause category: Discovery Gap (schema description out of sync with validator)

Framework layer that failed:

  • Component: create_task MCP tool, mem PKB server
  • File: wherever the tool's JSON Schema is generated and where the validator lives (Rust crate at ~/src/mem)

Expected vs Actual:

  • Expected: Either (a) the validator accepts the values listed in the schema description, or (b) the description lists only the values the validator accepts — i.e. the doc and the validator share a single canonical enum.
  • Actual: Documented type values bug, feature are rejected (and likely epic, learn, goal, project — untested). Documented status value active is rejected at create time. task and ready/in_progress are the only reliably-accepted values.

Reproduction

Both reproduce 100% on mcp__plugin_aops-core_pkb__create_task:

create_task(title: "x", type: "bug", ...)
→ Failed to create task: Invalid task type: bug

create_task(title: "x", type: "task", status: "active", ...)
→ Failed to create task: Invalid status: active

Suggested fix direction

Pick one canonical list per enum and propagate. Options:

  1. Doc matches validator: trim the parameter descriptions to only list values the validator accepts. Document the constraint in pkb-type-taxonomy.md (the spec already exists at specs/pkb/pkb-type-taxonomy.md).
  2. Validator matches doc: extend the validator to accept the values the description advertises, with semantic meaning for each.
  3. Single source of truth: define the type/status enum in one place (e.g. serde enum on the Rust struct with JsonSchema derived), so the description is generated from the validator.

Option 3 is the durable fix. Option 1 is the cheap fix.

Related context

  • An open user task is investigating exactly this taxonomy ambiguity for status: "check taxonomy for pkb. Which is canonical: status 'ready' or 'active'? confirm the linter agrees with the docs and the dashboard." Resolving the canonical list would unblock both threads.
  • The dashboard's spec view-dashboard.md and planning-web.md reference statuses like active, blocked, done, waiting, review, cancelled and node types like goal, project, epic, task, action, bug, feature, review, learn. Whatever canonical list lands needs the dashboard renderer aligned to it.

Criticality

Medium. Workaround exists (type: task + tags) but loses structural information about each task's intended kind, and forces every caller to discover the gap by trial and error. Recurring friction every time a new caller (human or agent) tries create_task with documented values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcriticality:mediumAnnoyance, minor efficiency loss

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions