Skip to content

patch: relative external target skips permission and returns blank error #37687

Description

@kitlangton

Summary

A valid functions.patch call containing a non-empty patchText payload returned a completely blank tool error. Subsequent retries in the same turn lost their arguments and were submitted as invalid empty calls, preventing the requested edit and leaving neither the user nor the model with an actionable error.

Environment

  • opencode version: 0.0.0-next-15652 (running session); the unrelated opencode executable currently on PATH reports 0.0.0-beta-202607151444
  • OS: macOS 25.5.0, arm64 (Darwin 25.5.0)
  • Terminal: WarpTerminal v0.2026.07.01.09.21.stable_01; TERM=xterm-256color; COLORTERM=truecolor
  • Shell: /bin/zsh
  • Install/channel: next
  • Active plugins: configured plugins are @warp-dot-dev/opencode-warp, @kitlangton/opencode-session-recap, and a local OpenCode debug-workspace plugin; local plugin files also exist for cmux feed/session integration and voice
  • Model: openai/gpt-5.6-sol-fast
  • Session: ses_099291c64ffep0rHSS1Yl4mq42

Reproduction

  1. Open a session in one repository and ask the agent to edit files in an approved sibling checkout using functions.patch.
  2. Have the agent submit a syntactically valid call with a non-empty patchText containing normal Update File operations, with targets such as ../opencode-quark-timeline/packages/simulation/package.json.
  3. Observe that the patch tool returns Tool error: with no error text.
  4. Allow the agent to retry and observe calls degrading to an empty/invalid payload, reported as Invalid JSON input for openai-responses tool call patch.

The exact sequence in this session was:

functions.patch({})
=> Invalid JSON input for openai-responses tool call patch

functions.patch({"patchText":"*** Begin Patch\n*** Update File: ../opencode-quark-timeline/...\n...\n*** End Patch"})
=> Tool error:

functions.patch({})
=> Invalid JSON input for openai-responses tool call patch

The middle call contained a complete multi-file patch, not {}. The target sibling checkout was covered by the configured external-directory permission.

Expected Behavior

The valid call should apply the patch. If a path, permission, patch hunk, or tool-runtime condition prevents it, the tool should return a specific structured error to the model and UI. A failed call must not cause later calls to lose a required patchText argument.

Actual Behavior

The valid call failed with a blank error:

Tool error:

The model had no diagnostic to act on. Its following patch attempts were serialized or emitted without the required input and OpenCode reported:

Invalid JSON input for openai-responses tool call patch

No files were edited.

Additional Context

  • Reproduced repeatedly in this session after the first blank failure.
  • The worktree remained clean, confirming that the valid patch was not partially applied.
  • The attempted patch updated TypeScript/JSON files in an open-source sibling checkout; no credentials or private data were involved.
  • Related closed issue [Bug] GPT-5.4 repeatedly sends empty apply_patch tool calls ({}), causing Tool execution aborted, while GPT-5.3 Codex does not #20227 reports repeated empty apply_patch {} calls, but this session captured a valid non-empty patch call reaching the tool and producing a blank error before retries lost their arguments.
  • Related open issue Empty bash tool arguments {} can still be submitted and interrupt the session #27871 covers empty required tool arguments interrupting a session. This report additionally concerns missing error propagation from a valid patch invocation.
  • A useful regression test would submit a valid patch against an approved external/sibling target, assert either success or a non-empty typed rejection, and verify that the next tool call retains its arguments after failure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions