Skip to content

codex exec skips persisted trusted project hooks unless --dangerously-bypass-hook-trust is passed #32491

Open

Description

@claude-ai-netra

Summary

On Codex CLI 0.144.1, noninteractive codex exec does not dispatch a project UserPromptSubmit hook that Codex app-server hooks/list reports as enabled and trusted. The same hook runs when --dangerously-bypass-hook-trust is supplied.

Reproduction

A repository has .codex/hooks.json with a UserPromptSubmit command hook that returns a blocking response. Persist trust for that project hook, then verify through app-server hooks/list:

  • enabled: true
  • trustStatus: trusted
  • current hash matches the manifest
  • no warnings/errors

From both repository root and a nested directory:

  1. Run codex exec without --dangerously-bypass-hook-trust, using an invalid model slug so provider traffic is easy to distinguish.
  2. The hook is skipped and the request reaches provider/model validation (HTTP 400).
  3. Repeat with --dangerously-bypass-hook-trust.
  4. The hook dispatches and blocks before provider traffic; the turn completes with zero input/output tokens.

Nested manifest discovery itself works: hooks/list returns the same trusted project hook key/hash from root and nested cwd.

Expected

A project hook reported as persisted rusted runs in codex exec without a dangerous trust-bypass flag. The bypass flag should remain an explicit override, not the only way to activate already-trusted hooks.

Actual

Persisted trust is ignored by noninteractive exec; the hook runs only with --dangerously-bypass-hook-trust.

Environment

  • codex-cli 0.144.1
  • Windows 11 / PowerShell
  • Project UserPromptSubmit command hook

A privacy-preserving downstream reproduction is tracked at anthony-chaudhary/fak#3939.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    windows-osIssues related to Codex on Windows systems
    execIssues related to the `codex exec` subcommand
    hooksIssues related to event hooks
    on Jul 11, 2026
  2. nordscope-fi commented on Aug 9, 2026

    @nordscope-fi

    Not reproducing on 0.147.0 (macOS): with trust persisted and no bypass flag, codex exec dispatched both hooks I registered.

    Reporting a negative result, since the version has moved on from the 0.144.1 in the original report and a data point either way seems useful.

    Setup

    • codex-cli 0.147.0, macOS 26.5.2, arm64
    • Throwaway CODEX_HOME, fresh repository, everything committed
    • [projects."<repo>"] trust_level = "trusted"
    • Two project hooks in <repo>/.codex/hooks.json: a PreToolUse command hook on apply_patch|Write|Edit|MultiEdit, and a UserPromptSubmit command hook with an empty matcher, which is the event in the original report
    • Trust granted through the startup prompt, then verified with hooks/list: trustStatus: trusted, enabled: true, source: project

    Run

    codex exec --approve-for-me --skip-git-repo-check "Edit notes.md so its body reads exactly: …" < /dev/null
    

    No --dangerously-bypass-hook-trust.

    Result

    hook: UserPromptSubmit
    hook: UserPromptSubmit Completed
    hook: PreToolUse
    hook: PreToolUse Completed
    

    Both handlers ran for real, not just in the status line. The UserPromptSubmit tracer wrote its payload file, and the PreToolUse hook's additionalContext arrived in the rollout as a developer message.

    What did reproduce

    An untrusted hook is skipped in codex exec with nothing printed at all: no warning, no mention in the run output, exit 0. That is the documented trust rule, but non-interactive mode is the one place where the prompt cannot be offered, so it is also the place where the skip is least visible. Worth a line on stderr naming the count and the reason, since hooks/list already computes both.

    A note on persisting trust, for anyone else testing this

    Trust is stored under [hooks.state], keyed exactly as hooks/list reports:

    [hooks.state."<sourcePath>:<event>:<group index>:<hook index>"]
    trusted_hash = "sha256:…"     # the `currentHash` field from hooks/list

    Writing that entry makes a subsequent headless run start trusted, which is what let me test the second event without a second keyboard approval. Obviously only sensible against a throwaway CODEX_HOME and a hook you wrote yourself.

    Happy to re-run against a different event or a nested working directory if that would help narrow what differs from the original report.

  3. JulienJBO commented on Aug 25, 2026

    @JulienJBO

    Current-platform retest (2026-08-26): I cannot reproduce this on Codex CLI 0.149.0 on macOS 26.6.2 (arm64).

    I used a fresh Git repo with a project .codex/config.toml declaring a blocking UserPromptSubmit command hook, plus a fresh CODEX_HOME. The app-server flow was:

    1. hooks/list -> project hook discovered as untrusted, with a currentHash.
    2. config/batchWrite -> persisted that exact hash under hooks.state.
    3. A fresh hooks/list -> the same hook reported trusted.
    4. codex exec without --dangerously-bypass-hook-trust -> the hook ran and blocked before the provider request.
    5. Repeated from a nested directory in the same repo -> the trusted project hook ran again.

    This agrees with the earlier macOS 0.147.0 report, but does not invalidate the original Windows reproduction. I therefore do not have a justified code patch from current macOS behavior. The remaining investigation looks Windows-specific and may overlap #40247; an exact current Windows retest would be the useful next discriminator.

  4. Chad-NewmanCRE commented on Sep 29, 2026

    @Chad-NewmanCRE

    Windows retest on 0.158.0-alpha.2.1

    The existing issue reports the same trusted-but-skipped Windows exec symptom on 0.144.1. This newer reproduction is consistent with that report, but does not establish an identical internal cause. No trust-bypass comparison was performed.

    Environment

    • Windows desktop Store package: OpenAI.Codex 26.924.6891.0.
    • App-reported version: 26.924.51851, build 12111, prod channel.
    • Active and bundled CLI: 0.158.0-alpha.2.1.
    • Microsoft Store package-manager check on September 29, 2026: no newer eligible package available.

    Expected behavior

    A trusted project-local command hook for UserPromptSubmit should run on a substantive prompt, append its additionalContext, and create its local metadata-only receipt. PostToolUse should record the matching context-command outcome. Stop should check that turn's state.

    Observed behavior

    All three hooks are returned by hooks/list as enabled, trusted and project-scoped, with no errors or warnings. Both ordinary and extended Windows cwd forms return the same registration. The active local desktop session's diagnostics report feature.hooks=true.

    After a complete app restart and fresh substantive prompts, the hook's additionalContext and receipt are absent. No hook lifecycle event was observed. Directly invoking the exact configured Windows command through cmd.exe successfully runs the handler and creates a diagnostic receipt.

    Isolated reproduction

    The same installed CLI was invoked with exec --ephemeral --json --sandbox read-only against the same trusted project. A temporary loopback Responses-compatible fixture returned fixed text events. No AI inference or agent tool action occurred. Existing hook trust was preserved without a bypass flag or persistent configuration change.

    The CLI emitted thread.started, turn.started, a fixed assistant response and turn.completed. The captured request lacked the hook's expected additionalContext marker, and no receipt was created. A process-only features.hooks=true override produced the same outcome.

    Limits and question

    This narrows the failure to project-hook loading or execution but does not identify the internal cause. Because the custom Stop handler returns silently when prompt state is missing, absence of a Stop block is not independent proof that Stop was skipped. The initial fixture does not exercise a successful PostToolUse event.

    Is this a known Windows project-hook regression in 0.158.0-alpha.2.1, or is there an additional execution prerequisite not reflected in hooks/list? What supported diagnostic can show why a trusted command hook was not invoked?

    No credentials, business documents, hook trust hashes, private repository identifiers, local usernames, or chat transcript are included in this report.

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

    CLIIssues related to the Codex CLIbugSomething isn't workingexecIssues related to the `codex exec` subcommandhooksIssues related to event hookswindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions