Skip to content

[FEATURE]: tool.execute.error for failed tool calls (tool.execute.after is currently success-only) #27900

@haabe

Description

@haabe

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

opencode 1.15.1 documents tool.execute.before and
tool.execute.after as a paired event surface. Runtime test shows
they fire on different populations:

  • tool.execute.before fires for every tool call.
  • tool.execute.after fires only for successful tool calls.

A failed call (say, read on a nonexistent file) fires
tool.execute.before and routes the error to the message stream,
where the model receives and summarises it. No plugin-visible
after-side event fires. Neither session.error nor a flagged
message.part.updated fired in our test.

Use case: reflexion-style frameworks (retry-with-self-critique on
failure) need a plugin-observable failure signal. Wiring reflexion
on tool.execute.after alone is structurally broken; failures
bypass the hook entirely. The current workaround is to log callIDs
at before and reconcile orphans against the message stream, which
is fragile.

Possible shapes:

  • Add tool.execute.error for failed calls.
  • Make tool.execute.after fire for both success and failure with
    a status field. This breaks plugins that assume current
    semantics.
  • Document the success-only semantics explicitly at
    https://opencode.ai/docs/plugins/ so framework authors don't
    assume symmetry from the name pair.

Related: #25918 (tool.execute.after is declared but never
triggered) covers the same hook surface. If the fix there also
handles error paths, this request may be subsumed. Filing
separately because the failure-event question is distinct from
"after never fires" — in our test, .after does fire on success.

Reproduction:

  1. Install opencode-ai 1.15.1.
  2. Create .opencode/plugin/watch.js that logs every
    tool.execute.before and tool.execute.after call as JSON.
  3. opencode run "read ./does-not-exist.txt and report contents"
    with any tool-calling-capable model.
  4. Inspect log: before fires, after does not, despite the
    failure surfacing to the user in the CLI output.

Verified 2026-05-16 with local Ollama provider (llama3.1:8b
32k-ctx). Full reproduction context:
https://github.com/haabe/mycelium/blob/main/docs/receipts/cases/2026-05-16-opencode-phase1-runtime.md

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
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