codex exec executes commands but does not fire user hooks in 0.136.0-alpha.2

Resolved 💬 3 comments Opened Jun 2, 2026 by MoRezaeirad Closed Jun 4, 2026

Summary

codex exec can execute shell commands while user hooks configured in an isolated CODEX_HOME never fire. This happens even with:

  • [features].hooks = true
  • the project marked trusted in config.toml
  • --dangerously-bypass-hook-trust
  • hooks.json containing broad SessionStart, UserPromptSubmit, PreToolUse, and PostToolUse handlers
  • a tool matcher of .*

The result is that a command can run successfully, but hook-based command observation/enforcement is skipped without a clear error.

Environment

  • Codex CLI: codex-cli 0.136.0-alpha.2
  • Package: @openai/codex@0.136.0-alpha.2
  • Install path: npm global install
  • OS: Ubuntu 26.04 LTS, Linux 7.0.0-15-generic, x86_64
  • Node: v22.22.2

Minimal reproduction

This repro uses a temporary CODEX_HOME, configures hooks, uses a trusted project entry, bypasses hook trust, and asks codex exec to run one shell command.

set -eu

tmp="$(mktemp -d)"
codex_home="$tmp/codex-home"
work="$tmp/work"
marker="$tmp/hook-fired"

mkdir -p "$codex_home" "$work"

cat > "$codex_home/config.toml" <<EOF
[features]
hooks = true

[projects."$work"]
trust_level = "trusted"
EOF

cat > "$codex_home/hooks.json" <<EOF
{
  "SessionStart": [
    {
      "hooks": [
        { "type": "command", "command": "sh -c 'printf SessionStart\\n >> $marker'" }
      ]
    }
  ],
  "UserPromptSubmit": [
    {
      "hooks": [
        { "type": "command", "command": "sh -c 'printf UserPromptSubmit\\n >> $marker'" }
      ]
    }
  ],
  "PreToolUse": [
    {
      "matcher": ".*",
      "hooks": [
        { "type": "command", "command": "sh -c 'printf PreToolUse\\n >> $marker'" }
      ]
    }
  ],
  "PostToolUse": [
    {
      "matcher": ".*",
      "hooks": [
        { "type": "command", "command": "sh -c 'printf PostToolUse\\n >> $marker'" }
      ]
    }
  ]
}
EOF

cd "$work"
CODEX_HOME="$codex_home" HOME="$codex_home" \
  codex exec --sandbox workspace-write --dangerously-bypass-hook-trust \
  "run exactly: /bin/bash -lc 'printf command-ran > .command-ran'" \
  < /dev/null

echo "command artifact:"
ls -l .command-ran || true

echo "hook artifact:"
if [ -f "$marker" ]; then
  cat "$marker"
else
  echo "<missing>"
fi

Actual behavior

The requested shell command runs and creates .command-ran, but the hook marker file remains missing. In other words, command execution completed while all configured hooks fired zero times.

Observed on 0.136.0-alpha.2:

command artifact:
-rw-rw-r-- ... .command-ran
hook artifact:
<missing>

I also tested with JSON output enabled; the command appears as normal command execution, but no hook side effect occurs.

Expected behavior

At least one configured hook should fire. More specifically:

  • SessionStart should fire when the exec session starts, or the docs should state that codex exec does not emit session lifecycle hooks.
  • UserPromptSubmit should fire for the submitted exec prompt, or the docs should state that exec prompts bypass this hook.
  • PreToolUse and PostToolUse should fire around the shell command execution, especially with matcher: ".*" and --dangerously-bypass-hook-trust.

If codex exec intentionally does not support user hooks, the CLI should make that explicit. A hook configuration intended to observe or block commands should not silently become non-operative while commands still execute.

Why this looks like a Codex hook dispatch issue

The repro rules out the common configuration causes I could think of:

  • Hooks are explicitly enabled with the canonical [features] hooks = true setting.
  • The project is marked trusted.
  • Hook trust is bypassed with --dangerously-bypass-hook-trust.
  • The hook file is in the documented hooks.json location under CODEX_HOME.
  • PreToolUse and PostToolUse use matcher: ".*", so this should not depend on the shell tool name being Bash or something else.
  • The hook command only writes a marker file, so there is no policy response schema involved.

This leaves either hook discovery not happening under isolated CODEX_HOME during codex exec, hook dispatch not being wired for codex exec, or hooks being skipped silently in this code path.

Related issues

This appears related to, but not fully resolved by, prior reports about hook coverage in exec/non-interactive flows:

  • #18607
  • #20204
  • #24211

This issue is intended to provide a minimal standalone repro showing successful command execution with zero hook firing on 0.136.0-alpha.2.

View original on GitHub ↗

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