Skip to content

Built-in image generation does not appear to emit PreToolUse hooks #20616

Open

Description

@murphybread

What version of Codex is running?

Codex Desktop on Windows. Local CLI reports:

codex-cli 0.128.0

What platform is your computer?

Windows, PowerShell session.

What issue are you seeing?

PreToolUse hooks configured for built-in image generation matcher candidates did not fire before a real image_gen tool call. The same hook script blocks correctly when invoked with a simulated hook payload, so this looks like the built-in image generation call is not being emitted through the hook runtime.

I originally observed this on local CLI 0.124.0 and re-tested after updating the npm-installed CLI to 0.128.0. The behavior was unchanged in the tested Codex Desktop session.

Why this matters

Some projects need generated image assets to go through a wrapper that records provenance metadata, for example prompt/model metadata in EXIF, a manifest, or an asset ledger. If built-in image_gen cannot be observed or blocked by PreToolUse, that wrapper cannot be enforced before generation runs.

Steps to reproduce

  1. Enable Codex hooks in config.toml:
[features]
codex_hooks = true
  1. Register PreToolUse hooks for likely built-in image generation matcher names:
[[hooks.PreToolUse]]
matcher = "image_gen.imagegen"

[[hooks.PreToolUse.hooks]]
type = "command"
command = "python /path/to/check-image-generation-route.py"

[[hooks.PreToolUse]]
matcher = "imagegen"

[[hooks.PreToolUse.hooks]]
type = "command"
command = "python /path/to/check-image-generation-route.py"

[[hooks.PreToolUse]]
matcher = "image_generation"

[[hooks.PreToolUse.hooks]]
type = "command"
command = "python /path/to/check-image-generation-route.py"
  1. Use a hook script that exits non-zero for image generation events. I verified the script itself blocks when it receives a simulated image payload:
{"tool_name":"image_gen.imagegen","tool_input":{"prompt":"Project-bound website/app asset. Asset role: route validation."}}

The hook exited with code 2.

  1. Ask Codex Desktop to generate an image with the built-in image generation tool.

Actual behavior

The built-in image generation tool executed and saved an image under $CODEX_HOME/generated_images/.... The PreToolUse hook did not block the call and did not appear to receive the image tool event.

The generated file had no project provenance metadata when inspected with the local EXIF reader used by the provenance guard:

{
  "prompt": "",
  "model": ""
}

This does not prove whether image generation has no hook payload in all Codex builds, but in this tested Desktop session it shows the configured PreToolUse guard was not invoked before built-in image generation.

Expected behavior

Built-in image generation should emit a PreToolUse event before generation. The hook payload should include a stable hook-facing tool name, such as image_gen or image_gen.imagegen, and the prompt/options needed for policy decisions.

If the hook exits with the documented block/deny behavior, the image generation call should not execute.

Ideally, image generation should also emit PostToolUse with enough metadata to audit generated output paths, success status, and any generated file identifiers.

Additional context

Related issue/PR:

This issue is asking whether the built-in image generation handler needs the same kind of hook participation. From the outside, the symptom is the same class of problem: a built-in structured tool executes, but hook policy cannot observe or block it.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    hooksIssues related to event hooks
    tool-callsIssues related to tool calling
    on May 1, 2026
  2. github-actions commented on May 1, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. murphybread commented on May 2, 2026

    @murphybread
    Author

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

    여기 그대로 붙여 넣을 수 있는 영어 답변입니다:


    Not a duplicate of #20204, though they belong to the same family of "PreToolUse hook coverage gaps."

    The bot appears to have matched on the shared keywords (PreToolUse, hooks, tool handlers). The author of #20204 made a similar clarification when their issue was bot-flagged as a duplicate of #18491 — same logic applies here. Happy to coordinate scope with the #20204 PR if maintainers prefer, but flagging this as a distinct issue so the image-generation case isn't silently absorbed and lost.

  4. 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.

  5. chongxian1314 commented on Sep 23, 2026

    @chongxian1314

    Capability confirmation: pre-dispatch control for native image generation on macOS Desktop

    Draft for maintainer review; not submitted. This is a request for a supported control contract, not a confirmed macOS hook-bypass bug report.

    Environment and evidence boundary

    The target is Codex Desktop on macOS, using its built-in image generation/editing tool in a local project context. The exact Desktop build, embedded runtime version, active model and reasoning setting were not available through the permitted native metadata interface; all remain unknown. A separately installed CLI version is not being used to identify this Desktop runtime.

    The exposed image tool accepts a prompt and either local image references or recent conversation images. Its exposed schema has no output-directory, no-cache or per-call approval parameter. The locally available image instructions describe default native file output followed by optional copying elsewhere; inline presentation does not establish absence of a local artifact. These are schema/instruction observations, not results from a new generation.

    Two proposed scenarios use only a small synthetic image: one permits output solely inside <allowed-output>/; the other permits no generated-image or cache write anywhere. Neither scenario has been dispatched. No image service request or local hook experiment was made for this investigation, because a control covering the native path before side effects had not been established. This does not establish that every host lacks such a control, or that an agent failed to refuse.

    Relevant public references

    The hooks documentation describes denial for covered local tool paths, while allowing specialized paths to opt out. Some error cases continue execution. It therefore does not establish the fail-closed image boundary requested here.

    The permissions documentation scopes profiles to sandboxed local commands and distinguishes other capability controls. We have no evidence that a shell-only restriction covers this native image route.

    Issue #20616 reports missing image hook events on Windows, mentioning CLI versions 0.124.0 and 0.128.0. This is related reporter evidence, not a reproduction on our Mac or proof of its Desktop runtime version. Its linked PR #18391 was merged for apply_patch hook handling; that is not an image-path fix confirmation. We have not verified hooks failing locally.

    Requested capability and contract

    Please identify a supported mechanism and the applicable macOS Desktop build/runtime versions, or explicitly confirm which parts are currently unsupported:

    1. Decision timing. Can an independently enforced allow/deny decision stop the native image operation before its service request is dispatched and before the first generated image, intermediate image or image-cache artifact is written? A check after generation or a later copy/delete operation would not satisfy this requirement.
    2. Stable identity and coverage. What exact canonical tool/event identity and input schema apply? Does the same decision cover direct calls, nested code-mode calls, aliases and native edit/generate routes? Please identify exclusions rather than implying whole-host coverage. A tool name visible to the model is not assumed to be a valid hook matcher.
    3. Failure behavior. What happens when policy cannot load, a handler fails, returns malformed output, times out or becomes unavailable? Is a supported fail-closed mode available for this particular route? Please distinguish an explicit deny from an error that allows execution.
    4. Observable outcome. Which supported event or result proves that an attempted call was denied before dispatch? Can it distinguish attempted invocation, service dispatch and artifact creation without exposing prompts, identifiers or images? What runtime evidence confirms the intended policy actually loaded?
    5. Configuration and authority. Please provide the minimal supported configuration/interface, required administrative authority, version prerequisites and known limitations. We are not requesting a model instruction that merely asserts it has checked permissions, or a shell sandbox presented as control over every native tool.
    6. Safe validation. Is there a supported way to validate this boundary without allowing an actual image service request or image artifact write? If a test hides/replaces the tool, changes the consumer, or uses a mock service, please state what it proves and what remains untested on the actual Desktop path.

    The required prevention concerns the specified native image route, not an absolute guarantee about all host activity. Ordinary diagnostic metadata, if a supported test requires it, should have a separately declared scope; it must not silently include image artifacts.

    Acceptance and interim use

    Strict no-image-cache tasks are currently withheld from this native route. Ordinary image tasks that explicitly authorize native output remain subject to their own permissions; this request does not globally disable the feature.

    After a suitable control and its version applicability are established, separate authorized agent-behavior trials would still be needed. An agent declining to invoke the tool is the intended behavioral result. An attempted invocation stopped by the host demonstrates containment, not correct agent refusal. We have not run those trials or claimed this issue is fixed.

    No local files, configuration dumps, private paths or images accompany this draft.

  6. Sololyn commented on Sep 28, 2026

    @Sololyn

    Adding a capability-confirmation request for a per-generation budget/provenance gate on macOS Desktop. This is not a new reproduction of the Windows image-generation behavior reported above.

    The project needs each native image generation/edit operation to consume one approved permit before dispatch, and then reconcile that same operation with its actual outcome and output. An after-the-fact ledger or a model instruction to check the budget is not sufficient.

    Could maintainers clarify the currently supported interface and applicable Desktop/runtime versions for the following?

    1. A blocking decision before the native image service request, with the canonical tool/event name, complete relevant inputs, and an operation ID. Please specify whether direct and nested code-mode calls share this boundary or can be disabled through a supported control.
    2. A fail-closed mode when the policy handler is unavailable, times out, crashes, or returns invalid output; distinguish those cases from an explicit deny.
    3. A supported way to bind one project permit to one native operation, reject duplicate/replayed dispatch, and correlate success/failure/unknown outcomes and verifiable output identity.
    4. A status/recovery interface after a disconnect or restart, so an unknown operation is not automatically retried.
    5. A no-side-effect validation procedure for coverage and rejection before authorizing a real generation. If existing hooks cannot provide this contract, please confirm that limitation and the intended supported alternative.

    Evidence boundary: a local project shell-denial probe succeeded. In a separate native collaboration test, the project's pre-start permit was not consumed even though the child started; canonical-name/configuration/coverage explanations have not been ruled out. That observation does not establish the image path's behavior, and no new image call was made to test enforcement. A separately installed CLI 0.153.4 schema exposes image/collaboration result items and client dynamic tools, but we are not treating that CLI version or schema as proof of the Desktop runtime or native pre-dispatch coverage. Related collaboration concerns are discussed in #33284.

    Please point to the minimal supported configuration, version prerequisites and coverage limitations, or confirm which parts need a feature request. No private project files, images, transcripts, account details or local paths are included.

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

    appIssues related to the Codex desktop appbugSomething isn't workinghooksIssues related to event hooksimagentool-callsIssues related to tool callingwindows-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