Feature: PostToolUseFailure hook (failure-branch sibling of PostToolUse)
Problem
The PostToolUse hook fires only after a tool produces a successful output — run_post_tool_use_hooks is gated on success in core/src/tools/registry.rs. There is currently no hook surface for the failure branch: when a tool invocation errors, exits non-zero, times out, or returns an unsuccessful result. Hook authors who want to react to tool failures (diagnostics, automated retry guidance, failure telemetry, post-mortem capture) have no event to attach to.
Proposed design
Add a PostToolUseFailure hook event — the failure-branch sibling of PostToolUse:
- Matcher-bearing (matches on tool name) and turn-scoped — identical dispatch semantics to
PostToolUse. - Input mirrors the
PostToolUsecontract plus anerror_messagefield describing why the invocation failed. - Two failure sources are covered:
- handler error — tool identity recomputed from the pre-tool-use payload,
tool_response: null; - unsuccessful result — identity and the partial response taken from the post-tool-use payload.
- Fail-open: a failing hook subprocess never changes the underlying tool outcome.
This follows the established hook-event pattern (e.g. the recent SubagentStart / SubagentStop additions), so it is additive and low-risk to the rest of the hook system.
Why this is generic
Reacting to tool failures is a need independent of any particular integration — observability, retry/recovery UX, and failure analytics all want a hook here, and PostToolUse deliberately excludes the failure case. It rounds out the tool-lifecycle hook surface (PreToolUse → PostToolUse → PostToolUseFailure).
Offer
Per the contributing guidelines, I'm raising this as an issue first rather than an unsolicited PR. I have a complete, tested reference implementation against current main (enum variant, schema input/output wires + generated fixtures, dispatcher/runtime/registry wiring, unit tests; cargo fmt and clippy clean) and would be glad to submit a PR if the team feels this aligns with the roadmap and would like to invite one. Happy to iterate on the design (e.g. trimming the output contract to informational-only) based on your preferences.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗