Skip to content

ApplyPatchHandler doesn't emit PreToolUse/PostToolUse hook event. Hooks only fire for Bash tool. #16732

@mklikushin

Description

@mklikushin

What version of Codex CLI is running?

0.118.0

What subscription do you have?

ChatGPT Plus

Which model were you using?

No response

What platform is your computer?

Darwin 24.6.0 arm64 arm

What terminal emulator and version are you using (if applicable)?

No response

What issue are you seeing?

PreToolUse and PostToolUse hooks registered via hooks.json never fire for file writes made through apply_patch. They only fire for Bash/shell tool calls.

Two root causes in the CLI source:

ApplyPatchHandler in registry.rs uses the default None implementation for pre_tool_use_payload() / post_tool_use_payload() (lines 63-65 of the trait), so the hook runtime skips it entirely.

hook_runtime.rs hardcodes tool_name: "Bash" (line 131) in both run_pre_tool_use_hooks and run_post_tool_use_hooks, so even if payloads were emitted, they'd be misidentified as Bash calls.

This means hook-based file access control, audit logging, or write coordination cannot cover the primary file write path.

What steps can reproduce the bug?

  1. Create a hooks.json with a PreToolUse hook command that logs all invocations to a file
  2. Ask Codex to edit a source file (triggers apply_patch)
  3. Ask Codex to run a shell command (triggers Bash)
  4. Check the log, observe only the Bash call appears and the file edit is missing

Tested with Codex CLI v0.118.0. Hook log captured 4 entries (2 PreToolUse + 2 PostToolUse), all with tool_name: "Bash" for sed and rg calls. The apply_patch call that actually modified the file produced zero hook events.

What is the expected behavior?

PreToolUse and PostToolUse hooks should fire for apply_patch with tool_name: "ApplyPatch" (or similar) and a payload containing the file paths being modified, consistent with how Bash tool calls emit hook events.

Additional information

We're building multi-agent orchestration that coordinates file writes across Codex, Claude Code, and OpenCode. Claude Code's SDK fires PreToolUse hooks on Write/Edit/MultiEdit tools, which lets us implement file-level locking between agents. This is foundational for implementing checkpoints in an environment where multiple agents edit the same worktree concurrently. Agents acquire a lock on a file before editing, providing a clear record of what changed and how to undo it.

Codex's hook infrastructure supports the same pattern architecturally, but apply_patch not opting in blocks the integration. The fix is scoped, implement pre_tool_use_payload() on ApplyPatchHandler and parameterize tool_name in hook_runtime.rs. Happy to elaborate on the use case or provide more analysis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghooksIssues related to event hooks

    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