openai / openai/codex

[Hooks] interrupt_agent does not dispatch SubagentStop for interrupted child

Open
#38,142 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI hooks subagent
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 SubagentStart hook event;
  • two siblings that completed normally each produced SubagentStop;
  • interrupt_agent was called for the remaining running child and returned previous_status: running;
  • that child's rollout immediately recorded a terminal turn_aborted event with reason interrupted;
  • the child was no longer running;
  • no SubagentStop event was dispatched for that child's exact agent_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?
  1. Configure trusted command hooks for both SubagentStart and SubagentStop. Have each append the event name and agent_id to an event log.
  2. Start a parent Codex session and spawn a subagent that remains running long enough to interrupt.
  3. Confirm that SubagentStart was recorded for the child.
  4. Call the native interrupt_agent tool for that running child.
  5. Confirm that the child is no longer live and that its turn ended as interrupted.
  6. 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:

  • Stop does not identify the child agent;
  • SessionEnd does not run for subagents;
  • the observed interrupt_agent tool input/output identifies the logical target but does not return the child's exact provider agent_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 SubagentStart and normal-completion SubagentStop hooks worked, and only the interruption path omitted the terminal event.

Contributor guide

Open the contributing guide

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.

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.