User-level ~/.codex/hooks.json PostToolUse ignored while plugin PostToolUse runs

Open 💬 2 comments Opened May 23, 2026 by jakobtfaber

Version: codex-cli 0.133.0
Platform: macOS arm64 (Apple Silicon)
Binary: /Users/jakobfaber/.nvm/versions/node/v24.13.1/bin/codex

Observed Behavior:

  • User-level ~/.codex/hooks.json works perfectly for SessionStart, UserPromptSubmit, PreToolUse, and Stop.
  • Adding user-level PostToolUse with standard schema does not execute in the live session (e.g. /tmp/user-posttooluse.log is never written).
  • Under the same tool emission and trust-bypass conditions, plugin-level PostToolUse (e.g., warp@claude-code-warp, remember@claude-plugins-official, and memory-doc-audit@memory-doc-audit-local) executes successfully.
  • No trust entries are ever generated in ~/.codex/config.toml for ~/.codex/hooks.json:post_tool_use:0:0 (nor is the user prompted to trust it), whereas trust entries exist for all other user-level hooks (pre_tool_use, session_start, stop, user_prompt_submit) and plugin-level post_tool_use hooks (e.g. warp@claude-code-warp:hooks/hooks.json:post_tool_use:0:0).
  • --dangerously-bypass-hook-trust bypasses trust check but still fails to trigger user-level PostToolUse, proving it is never discovered/registered in the event dispatcher.

Expected Behavior:
User-level PostToolUse loaded from ~/.codex/hooks.json should be discovered and run on the same supported tool emissions as plugin-level PostToolUse hooks.

Step-by-step Reproduction (Live Session):

  1. Write ~/.codex/hooks.json containing a command hook for "PostToolUse" (e.g. executing "echo USER_POSTTOOLUSE_FIRED >> /tmp/user-posttooluse.log").
  2. Run any command via the interactive Codex CLI that completes successfully (e.g. running "ls" via the shell tool).
  3. Check /tmp/user-posttooluse.log — it is missing or empty, indicating the hook never ran.
  4. (Contrast) Configure the same hook inside a local plugin's hooks/hooks.json. Add and enable the plugin via "codex plugin add".
  5. Run the same command — the plugin-level hook triggers successfully, proving the tool-use hook execution engine itself is functioning.

Evidence:

  • Official developer docs list ~/.codex/hooks.json and show PostToolUse in the hook schema.
  • codex-rs/config/src/hook_config.rs includes PostToolUse.
  • codex-rs/hooks/src/engine/discovery.rs is intended to load config-layer hooks.json and plugin hooks into the same handler list.
  • codex-rs/hooks/src/engine/discovery.rs applies bypass_hook_trust to both config-layer and plugin hooks.
  • codex-rs/core/src/tools/hook_names.rs says apply_patch matcher aliases include Write and Edit.

Caveat:
An isolated "codex exec" test harness with a fake CODEX_HOME/HOME fails to run ANY hooks (including SessionStart/Stop), meaning "codex exec" suffers from broader sandbox-masking / hook-loading limitations. The bug must be diagnosed and verified in a live interactive session.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗