submit_plan with missing edits aborts with "Tool execution interrupted" instead of returning a recoverable error

Closed Beginner friendly
#2,227 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
tooling

Research direction

Read apps/opencode-plugin/index.ts where the submit_plan arguments are declared, then check apps/opencode-plugin/submit-plan-executor.ts and its tests for the existing missing-edits guard. Make the registered tool accept omitted edits and confirm a call with {} returns the friendly error without opening the review flow.

Written by the indexing model from the issue text.

Description

bug triage
What happened?

When submit_plan is called without the required edits argument (for example, the model emits an empty/malformed tool call), OpenCode reports the tool call as interrupted instead of returning the existing friendly "No edits provided" error. No Plannotator review window opens, no plan backing file is created, and the agent gets no actionable error to recover from.

This is easy for a model to hit because submit_plan is an edit-based tool and a malformed call can omit edits entirely.

Plannotator version

0.28.32

OS

macOS 27.0.1

Agent

OpenCode

Where did it happen?

Plan review

Steps to reproduce
  1. Use OpenCode 2.1.4 with @plannotator/[email protected] and the plan-agent workflow.
  2. In Plan mode, call submit_plan with {} (missing edits), or any malformed arguments object without edits.
  3. Observe the tool result: Tool execution interrupted.
  4. Observe that no Plannotator review UI opens and no ~/.plannotator/active/<project>/_active-plan.md is created.

Calling submit_plan with {"edits":[]} is different: it reaches executeSubmitPlan and returns Error: No edits provided..., which the agent can recover from. The problem is specifically the missing field being rejected before execute.

Expected behavior

The tool should return a normal, recoverable tool result such as:

Error: No edits provided. Pass at least one edit with start and content.

The agent can then retry with a valid edits array. No review UI should open for an invalid call.

Actual behavior

OpenCode aborts the tool call with a generic Tool execution interrupted, so the agent does not know why it failed and cannot correct the call. The user sees no review window and no useful error either.

Root cause
  • apps/opencode-plugin/index.ts declares edits as a required tool argument:
    args: {
      edits: tool.schema.array(...)
    }
    
  • OpenCode validates tool arguments before calling execute, so executeSubmitPlan never runs.
  • The friendly guard already exists in apps/opencode-plugin/submit-plan-executor.ts:
    if (!invocation.edits || invocation.edits.length === 0) {
      return "Error: No edits provided. Pass at least one edit with start and content.";
    }
    
    but it is unreachable when the schema rejects the missing field first.
  • OpenCode then surfaces the validation failure as an interrupted tool call rather than a tool error the model can read.
Suggested fix

Plugin-side, make edits optional in the tool argument schema and let the existing executor guard handle it:

args: {
  edits: tool.schema
    .array(
      tool.schema.object({
        start: tool.schema.number(),
        end: tool.schema.number().optional(),
        content: tool.schema.string(),
      }),
    )
    .optional(),
},

Alternatively use .default([]) if OpenCode applies schema defaults before execute. Keep the executor guard as the single source of the friendly error.

Add a regression test for missing/empty edits:

  • executeSubmitPlan({ edits: undefined, ... }) returns the friendly error.
  • Ideally an integration test that calls the registered tool with {} and asserts it does not throw/abort.

Broader fix (OpenCode side): schema validation failures should be returned as recoverable tool errors with the validation message, rather than as Tool execution interrupted. That would make any tool with invalid arguments self-correctable.

Additional context
  • The tool result was the only signal: Tool execution interrupted.
  • No submit_plan entry reached the Plannotator plan review flow, and no active plan file was created for the project.
  • This is not the same as the existing OpenCode TUI rendering bug in #1893; the TUI itself is not involved here.
Dominant language
TypeScript
Stars
8.7k
Forks
649
Avg merge
8h 39m
Merged PRs (30d)
680

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from backnotprop/plannotator

All issues in backnotprop/plannotator

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.