Skip to content

Hooks: PostToolUse is missing for tools that complete via exec session / polling path #16246

Closed

Description

@avivcarmis-bb

Summary

Codex emits PreToolUse for shell tools started via exec_command, but in some cases it never emits the matching PostToolUse.

This appears to happen specifically when the command does not complete on the initial exec_command call and instead completes later through the long-running session / polling path.

Expected behavior

Every tool call that emits PreToolUse should emit exactly one matching PostToolUse when the tool finishes, regardless of whether it:

  • completes immediately on the initial tool call, or
  • completes later through the session continuation / polling flow

Actual behavior

PostToolUse is emitted for commands that complete immediately, but is missing for commands that:

  1. start via exec_command
  2. return a running session
  3. later complete through the session / polling path

Evidence

In one reproduced case, a single turn produced:

  • 7 PreToolUse
  • 2 PostToolUse

The transcript for that same turn showed that the missing tool calls did in fact complete successfully later, including exit codes and output, but no PostToolUse event was emitted for them.

The missing cases were long-running shell commands that first returned a session and later completed through polling. The two cases that did get PostToolUse were commands that completed directly on the initial exec_command path.

Impact

Consumers that rely on hooks to model tool lifecycle get incomplete traces:

  • tools appear to start but never finish
  • duration and status are missing
  • downstream systems cannot reliably pair pre/post tool events

Root-cause hypothesis

The hook integration appears to emit PostToolUse only for the immediate completion path, but not for tool completion that happens later through the exec session continuation / polling path.

Suggested fix

Emit PostToolUse when the tool actually completes, regardless of whether completion happens:

  • during the initial exec_command, or
  • during later session polling / continuation

The emitted event should use the original tool call ID so consumers can pair it with the earlier PreToolUse.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    tool-callsIssues related to tool calling
    on Mar 30, 2026
  2. added
    agentIssues related to the core agent loop
    and removed
    CLIIssues related to the Codex CLI
    tool-callsIssues related to tool calling
    on Mar 30, 2026
  3. JaysonGeng commented on Mar 31, 2026

    @JaysonGeng

    I put together a fix on my fork.

    Commit: 5dc02db
    Branch: fix/post-tool-use-on-exec-session-completion
    Fork compare: JaysonGeng/codex@main...fix/post-tool-use-on-exec-session-completion
    Upstream compare: https://github.com/openai/codex/compare/main...JaysonGeng:codex:fix/post-tool-use-on-exec-session-completion?expand=1

    What changed:

    • PostToolUsePayload is now computed before handler output is type-erased, so unified_exec can attach completion metadata from ExecCommandToolOutput.
    • Long-running exec_command sessions preserve the original tool call ID and raw cmd, and reuse them when write_stdin reports completion.
    • Added a unit regression for the write_stdin completion payload and a hooks integration regression for exec_command -> write_stdin -> completion.

    Validation:

    • cargo check -p codex-core --tests
    • ./target/debug/deps/codex_core-db6849df46c54ae2 tools::handlers::unified_exec::tests::write_stdin_post_tool_use_payload_uses_original_exec_call_id_and_command_on_completion --exact
    • ./target/debug/deps/all-677a7268d57df65b suite::hooks::post_tool_use_exit_two_replaces_one_shot_exec_command_output_with_feedback --exact
    • ./target/debug/deps/all-677a7268d57df65b suite::hooks::post_tool_use_fires_when_exec_session_completes_via_write_stdin --exact
    • just fmt
    • just fix -p codex-core
    • git diff --check

    just argument-comment-lint could not run locally because bazel is not installed in this environment.

    I know docs/contributing.md says external contributions are by invitation only, so I’m posting the compare links here instead of opening a PR.

  4. added
    sessionIssues involving session (thread) management, resuming, forking, naming, archiving
    and removed
    agentIssues related to the core agent loop
    on Apr 11, 2026
  5. added a commit that references this issue on Apr 23, 2026
    eed0e07
  6. added a commit that references this issue on Apr 23, 2026
    3cbeb1e
  7. added a commit that references this issue on May 7, 2026
    c2848cb
  8. oxysoft commented on May 8, 2026

    @oxysoft

    Indexed this hook ticket in the umbrella tracker: #21753

    Goal: collect the scattered Codex hook requests and bugs into one parity matrix for Full Claude Code Hook Parity (29+), while preserving this issue as the detailed thread for its specific behavior.

  9. added a commit that references this issue on Jun 27, 2026
    8042a56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghooksIssues related to event hookssessionIssues involving session (thread) management, resuming, forking, naming, archiving

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions