Skip to content

Native apply_patch lacks per-call workdir context for Hooks in multi-worktree repositories #20879

Open

Description

@kepuryou

What version of Codex are you using?

codex-cli 0.128.0

What platform is your computer?

Ubuntu 24.04 desktop, GNOME / Wayland, bash shell.

What issue are you seeing?

In a repository that uses multiple Git worktrees, the native apply_patch tool does not appear to have a per-call working directory / workdir field. This makes it impossible for project hooks to distinguish between the session working directory and the actual task worktree where an edit should be applied.

This becomes a practical bug when the Codex session starts in the primary checkout, then the agent switches to a task worktree for development:

  • exec_command supports workdir, so shell commands can correctly run inside the task worktree.
  • Native apply_patch does not expose an equivalent per-call workdir in its hook payload / tool input.
  • A cd performed by a previous shell command does not change the native apply_patch tool's working directory.
  • A project PreToolUse hook therefore only sees the session cwd, which may still be the primary checkout.
  • If the hook is strict about preventing edits from the primary checkout into task worktrees, it has to block native apply_patch even though the intended target is the current task worktree.

Observed failure from a strict project hook:

Command blocked by PreToolUse hook
Event: pre-tool-use
Status: block
Command: apply_patch
Checks:
- native-apply-patch-primary-worktree-guard:
  editing context error: applying a patch from the primary worktree context is not allowed for repository/task-worktree files

The only reliable workaround is to avoid the native apply_patch tool and instead run a one-shot shell patch through exec_command with an explicit workdir, for example:

apply_patch <<'PATCH'
*** Begin Patch
*** Update File: relative/path/from/task/worktree
@@
-old
+new
*** End Patch
PATCH

with the tool call itself carrying workdir=<task-worktree>. That works, but Codex warns that apply_patch should be used via the native tool instead of exec_command, which conflicts with the needs of strict worktree-aware hooks.

What steps can reproduce the bug?

  1. Create a repository with a primary checkout and a task worktree, for example:
git worktree add .worktrees/demo-task -b task-demo-task
  1. Start Codex from the primary checkout.
  2. In the conversation, ask the agent to continue in .worktrees/demo-task.
  3. Verify that shell commands can run in the worktree when exec_command is given workdir=.worktrees/demo-task.
  4. Attempt to edit a file with the native apply_patch tool.
  5. Observe that hooks only receive the session/root cwd for the native apply_patch call, not the task worktree cwd.
  6. A strict hook must either block the edit or risk allowing primary-checkout-to-worktree writes.

What is the expected behavior?

Native apply_patch should support an explicit per-call working directory, or Codex should otherwise pass the intended execution/editing cwd to hooks for apply_patch calls.

Ideally, native apply_patch should behave consistently with exec_command(workdir=...):

  • hooks can see the effective cwd for the patch;
  • relative paths inside the patch are resolved against that effective cwd;
  • multi-worktree projects can safely enforce "edit only inside the active task worktree" policies;
  • agents do not need to use shell apply_patch as a workaround.

Additional information

This is related in theme to worktree targeting problems such as #16525, but it is not the same issue. That report is about Codex Desktop on Windows producing a malformed cwd for worktree threads. This report is about Codex CLI native apply_patch lacking per-call workdir context for Hooks and multi-worktree repositories.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    hooksIssues related to event hooks
    tool-callsIssues related to tool calling
    on May 3, 2026
  2. 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.

  3. briancl2 commented on Aug 6, 2026

    @briancl2

    Adding a concrete multi-worktree incident that reinforces the per-call workdir request: https://github.com/briancl2/build-meta-analysis/issues/1559#issuecomment-5207186363

    A coordinator created and declared a dedicated owner worktree, but its effective process CWD remained the parent checkout. A relative native apply_patch targeted the parent checkout because the native call had no explicit per-call workdir. The planned paths were immediately restored, the patch was reapplied with absolute target paths, and an independent review verified the parent checkout clean.

    An explicit native apply_patch(workdir=...)—included in tool input and hook context—would make the target atomic and remove the need for absolute-path patch payloads or shell workarounds. This is one recovered macOS/internal-subagent case, not an all-platform recurrence claim.

  4. svejda-cz commented on Oct 10, 2026

    @svejda-cz

    I can reproduce a related failure on native Windows with multiple worktrees: apply_patch wrote to the primary worktree instead of the intended task worktree. Shell commands with an explicit workdir targeted the intended worktree correctly
    #52885

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 workinghooksIssues related to event hookstool-callsIssues related to tool calling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions