Skip to content

Codex cannot commit in a plain checkout: the default sandbox refuses writes under .git/ #1747

Description

@suleimansh

🤖 curated · Fable 5, effort high

The Codex driver runs codex exec --sandbox workspace-write (packages/agent-driver/src/codex.ts:104). Under that policy Codex keeps a .git/ directory at the workspace root read-only, so a Codex agent started in a plain checkout fails on its first commit or branch rename:

fatal: Unable to create '<checkout>/.git/index.lock': Operation not permitted
exit=128

In a worktree this does not happen: .git is a file there, the real git dir lives under the parent's .git/worktrees/<id>, and Codex lets both the commit and git branch -m through. So agents in checkouts The Framework creates (.branches/<id>/) are fine. The case that breaks is a Codex agent in a checkout that is a repository root — the non-owned-checkout run (the one that gets the "Branch management" fallback and is told to git checkout -b agent-<name> and commit), and any agent run in a clone of its own.

Verified (codex-cli 0.144.4, macOS)

  • Plain clone, codex exec -s workspace-write "git commit --allow-empty -m probe" → the error above, no commit.
  • Same, with the checkout's .git as a writable root — -c 'sandbox_workspace_write.writable_roots=["<checkout>/.git"]'[main a793efd] probe, exit 0.
  • Worktree of that clone, default sandbox, no extra roots: git commit -am … and git branch -m … both succeed.
  • A real task in a plain clone ("add a farewell line and commit it", with the branches skill present): Codex read the skill, tried branches name, edited the file, and ended with "I couldn't commit because this environment denies writes to .git".

Proposal

Keep workspace-write (the SPEC's "the agent may edit its workspace and nothing else" — .git/ is part of that workspace) and always pass the checkout's git common dir as a writable root: -c sandbox_workspace_write.writable_roots=["<git rev-parse --git-common-dir>"] next to -C <cwd>. Harmless in a worktree, and the plain-checkout case starts working. codex.SPEC.md gets the sentence that says why.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions