[Hooks] interrupt_agent does not dispatch SubagentStop for interrupted child
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- PR merge metrics
- PR metrics pending
Description
What version of Codex CLI is running?
codex-cli 0.147.0
What platform is your computer?
macOS 26.5, arm64
What issue are you seeing?
When a running subagent is interrupted through the native interrupt_agent tool, the child stops executing but Codex does not dispatch the documented SubagentStop hook for that child.
This leaves exact-ID lifecycle observers with a SubagentStart and no corresponding terminal event, so they must incorrectly retain the interrupted child as running indefinitely.
In one captured occurrence:
- three subagents each produced a
SubagentStarthook event; - two siblings that completed normally each produced
SubagentStop; interrupt_agentwas called for the remaining running child and returnedprevious_status: running;- that child's rollout immediately recorded a terminal
turn_abortedevent with reasoninterrupted; - the child was no longer running;
- no
SubagentStopevent was dispatched for that child's exactagent_id.
The hook configuration was active and functioning in the same parent turn, as shown by the two normal SubagentStop events. No transcript files or private paths are attached to this public report.
What steps can reproduce the bug?
- Configure trusted command hooks for both
SubagentStartandSubagentStop. Have each append the event name andagent_idto an event log. - Start a parent Codex session and spawn a subagent that remains running long enough to interrupt.
- Confirm that
SubagentStartwas recorded for the child. - Call the native
interrupt_agenttool for that running child. - Confirm that the child is no longer live and that its turn ended as interrupted.
- Inspect the hook event log.
Actual result: there is no SubagentStop event for the interrupted child's agent_id.
Control: allow another child in the same session to complete normally; its matching SubagentStop is dispatched.
What is the expected behavior?
Every subagent identity announced by SubagentStart should receive an exact terminal lifecycle event when it completes, fails, or is interrupted. With the current documented hook surface, that should be SubagentStop carrying the same agent_id.
Interruption should therefore dispatch SubagentStop exactly once after the child becomes terminal. If interruption is intentionally distinct from stop, Codex needs another documented exact-ID terminal hook; currently there is no such hook.
Why this matters
External lifecycle consumers cannot repair this safely from the other documented hooks:
Stopdoes not identify the child agent;SessionEnddoes not run for subagents;- the observed
interrupt_agenttool input/output identifies the logical target but does not return the child's exact provideragent_id; - parsing rollout transcripts is not a stable lifecycle interface.
Consequently, any observer that avoids timing or task-name heuristics can remain stuck in Running even though the interrupted child has stopped.
Related issues
- #37301 reports a parent repeatedly waiting after a child was interrupted; it may share the same missing terminal-notification boundary.
- #33700 tracks completed/interrupted descendants remaining persisted as open.
- #33097 is related to hook dispatch but appears distinct: in this reproduction
SubagentStartand normal-completionSubagentStophooks worked, and only the interruption path omitted the terminal event.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the native interrupt_agent handling and the SubagentStart/SubagentStop hook dispatch paths, comparing interruption with normal child completion. Reproduce the reported lifecycle sequence and verify that the interrupted child receives exactly one SubagentStop event with the same agent_id after becoming terminal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100