Relative write rules under :workspace_roots recursively expand across turns until process spawning fails with E2BIG

Open 💬 7 comments Opened Jul 16, 2026 by ryo88c

What version of the Codex App are you using (From “About Codex” dialog)?

26.707.72221 (Codex Desktop surface in the ChatGPT app; the affected session recorded embedded codex-cli 0.144.2)

What subscription do you have?

ChatGPT Pro (x20)

What platform is your computer?

Darwin 25.5.0 arm64 arm

What issue are you seeing?

When a custom permission profile grants relative write access to .git and
.agents under :workspace_roots, Codex Desktop appears to feed the derived
permission-path entries back into the workspace-root set on subsequent turns.
The same relative rules are then applied again, synthesizing increasingly deep
path strings such as:

<repo>/.git/.agents
<repo>/.git/.git/.agents
<repo>/.agents/.git/.agents/.git

These paths are entries in Codex's permission metadata; Codex did not create
the corresponding directories on disk. The four first-level nested paths
.git/.git, .git/.agents, .agents/.git, and .agents/.agents were absent
from the affected repository's filesystem when checked.

The workspace and writable-root sets grow on each turn. Eventually all local
process creation fails, including commands with almost no arguments such as
pwd:

Failed to create unified exec process: Argument list too long (os error 7)

Restarting the app does not repair a task whose stored permission context has
already expanded. Continuing in a new task is then required unless the task can
be recovered by other means.

In one affected task, the recorded permission context grew as follows:

| Time (UTC) | Workspace roots | Writable roots | Approx. permission-context size |
| --- | ---: | ---: | ---: |
| 03:22 | 2 | 5 | 3.8 KB |
| 03:40 | 4 | 9 | 6.5 KB |
| 04:33 | 22 | 45 | 33.5 KB |
| 05:01 | 62 | 125 | 99.2 KB |
| 05:09 | 126 | 253 | 207.3 KB |

This is not caused by a long shell command. Once the task reaches the failure
state, short commands such as pwd, sed, and git diff all fail before the
shell process starts.

What steps can reproduce the bug?

  1. On macOS, configure a custom permission profile that extends :workspace

and contains relative child write rules under :workspace_roots:

```toml
default_permissions = "main-workspace"

[permissions.main-workspace]
extends = ":workspace"

[permissions.main-workspace.filesystem.":workspace_roots"]
".git" = "write"
".agents" = "write"
```

  1. Start a new Codex Desktop task in a Git repository with that profile.
  2. Continue the same task across multiple user turns.
  3. Inspect the task's recorded turn_context values for

workspace_roots and sandbox_policy.writable_roots.

  1. Observe that derived permission-path entries from the preceding turn are

treated as new workspace roots and receive the same relative rules again,
even though the corresponding filesystem directories do not exist.

  1. Continue until the permission context becomes large enough that a local

command fails with Argument list too long (os error 7).

The affected session used embedded codex-cli 0.144.2. A comparison task using
0.144.0-alpha.4 with the same global configuration remained bounded across 61
recorded turn contexts: writable roots never exceeded 5 and workspace roots
never exceeded 6. This comparison suggests a regression between those builds,
but does not by itself identify the exact introducing commit.

The public 0.144.2 source intentionally expands each symbolic
:workspace_roots rule into a concrete path entry for every runtime workspace
root. That path-joining operation does not create directories. The unresolved
defect is why concrete permission-path entries derived in one turn were
included in the runtime workspace-root input of later turns. The available
evidence does not yet distinguish whether Codex Desktop supplied the expanded
set again or the app-server/runtime persisted or merged the wrong set.

This configuration is not the separate permissions.<profile>.workspace_roots
table used to add workspace roots. The official configuration model and the
0.144.2 parser distinguish that root-registration table from
permissions.<profile>.filesystem.":workspace_roots", which defines filesystem
access rules inherited by the existing workspace roots. Therefore, treating
the derived .git and .agents permission entries as new workspace roots on
later turns is not the documented meaning of this configuration.

What is the expected behavior?

Relative filesystem rules under :workspace_roots should be evaluated against
the original workspace-root set for the task. Permission-path entries derived
from those rules must not be fed back as new workspace roots on the next turn.

The effective workspace and writable-root sets should remain bounded and stable
unless the user or app explicitly adds a workspace root.

Additional information

A verified workaround is to remove the relative .git and .agents write
rules from :workspace_roots and grant write access to the required directories
using explicit absolute paths instead. After applying that workaround and
restarting Codex, two consecutive turns remained stable at 11 writable roots,
with no duplicates and no nested .git/.git, .git/.agents, .agents/.git, or
.agents/.agents writable roots.

Potentially related but not duplicate reports:

  • #31838 reports TUI latency with many statically configured workspace roots;

this report concerns roots generated recursively across turns until E2BIG.

  • #31269 reports a custom permission profile switching after the first prompt;

this report concerns recursive path materialization while the profile is in
effect.

I have retained the affected task ID and sanitized root-count evidence and can
provide additional diagnostics through an appropriate private support channel.
No repository names, user paths, or raw task logs are included in this report.

View original on GitHub ↗

7 Comments

caldwellshane · 1 month ago

I can independently reproduce this in Codex Desktop on macOS with an affected task using multiple workspace roots and relative .git grants.

Additional evidence from the affected task:

  • The live task preamble contains synthetic roots for every repository, including <workspace>/.git/.git/... through nine repeated .git segments. Matching hidden-path and .env rules are also expanded against those synthetic roots, multiplying the permission metadata.
  • Reloading the affected task after restarting Codex retained the expanded root set.
  • Even pwd, with its working directory set to an actual worktree rather than a path ending in /.git, fails before the shell starts:

``text
Script error:
execution error: Io(Os { code: 7, kind: ArgumentListTooLong, message: "Argument list too long" })
``

  • Retrying the same pwd with require_escalated fails identically. This places the failure before command execution and sandbox approval routing; changing the task to "Approve for me" cannot recover it.
  • Reads of required agent rules and the product's local diagnostic scripts fail with the same error, so the affected task cannot launch its own recovery diagnostics.

This appears to be the same permission-path feedback loop described in the issue. One recovery question for Desktop: can task resume/reload discard derived permission paths and recompute runtime workspace roots from the original project set? Restarting and reloading alone do not recover a task after the permission context has crossed the process-spawn limit.

TarjinderSingh · 1 month ago

Confirmed as well. Pretty much bricks the entire thing.

TarjinderSingh · 1 month ago

Update from my earlier confirmation: I retested the original permission pattern in a fresh task using codex-cli 0.145.0, with relative .git and .agents write rules under filesystem.":workspace_roots".

Across three consecutive turns, the workspace and writable-root sets remained stable. I observed no nested .git/.git, .git/.agents, .agents/.git, or .agents/.agents paths, and local process execution continued to work normally.

I restored the relative .git grant because normal Git operations need to modify protected repository metadata such as the index and refs. Therefore, permanently removing that rule is not an ideal workaround for a development-oriented permission profile.

This is preliminary evidence that the recursive expansion no longer reproduces in 0.145.0. The probe was limited to three turns, so I cannot yet confirm that the issue is fully resolved or identify the fixing change.

ryo88c · 20 days ago

I retested the original configuration after upgrading to Codex 0.146.1.

Test conditions:

  • Restored the relative .git and .agents write rules under :workspace_roots
  • Fully restarted Codex
  • Started a fresh task
  • Measured six distinct saved turn_context entries across six user turns

All six samples remained identical:

  • Workspace roots: 1 total / 1 unique
  • Writable roots: 2 total / 2 unique
  • Nested permission roots: 0
  • Permission entries: 18 total / 12 unique / 6 duplicates
  • Permission-context size: 2,151 bytes
  • pwd: succeeded on every turn
  • E2BIG: not reproduced

The complete permission context was also identical across all six samples.

Based on this regression test, I can no longer reproduce the recursive permission-root growth or the resulting E2BIG failure with the original relative
rules. This confirms the issue as resolved for my reported configuration, so I agree with keeping this issue closed.

This does not identify the specific fixing change or prove the behavior for every permission profile or workspace configuration, but no further action
is needed from my side.

TarjinderSingh · 19 days ago

Request to reopen: the recursive workspace-root expansion appears to have
returned after the earlier successful regression tests.

I previously reported that the original permission pattern remained stable on
0.145.0. I now have another two-snapshot reproduction with the same feedback-loop
signature. The current installation is codex-cli 0.147.0 on macOS 26.6.1 arm64.

The active custom profile retains the original rules:

[permissions.repo-dev.filesystem.":workspace_roots"]
"." = "write"
".git" = "write"
".agents" = "write"

There were no configuration changes between snapshots.

| Metric | First snapshot | Second snapshot |
|---|---:|---:|
| Workspace roots | 2 | 34 |
| Writable roots | 38 | 102 |
| Unique root union | 38 | 102 |
| Minimal pwd spawn | 0.061 s | 5.886 s |

The second snapshot contained another generated suffix layer, including paths
such as:

  • .agents/.agents/.agents
  • .agents/.git/.git
  • .codex/config.toml/.agents
  • .codex/config.toml/.git

Codex Doctor reports that config.toml parses successfully and that the sandbox
configuration is readable. This therefore does not appear to be a malformed-TOML
or ordinary shell problem.

As a control, a fresh Desktop task using its managed five-entry permission
profile has remained stable across three saved turn contexts: two workspace
roots, one sandbox writable root, zero suspicious nested roots, and normal
process spawning. That control does not exercise the custom repo-dev profile,
so I am continuing the equivalent custom-profile regression test separately.

I searched the currently open openai/codex issues and did not find a new report
covering this same recursive root-growth/E2BIG failure.

genzorr · 18 days ago

Independent reproduction of the returned regression on current macOS Desktop:

  • ChatGPT Desktop 26.803.41515 (build 6321), embedded codex-cli 0.147.0-alpha.6.5
  • macOS 26.5.2 arm64
  • The profile granted ".", ".git", and ".codex" writes under filesystem.":workspace_roots".

In one thread, requestRuntimeWorkspaceRootCount and turn/start acknowledgement latency grew together:

| Runtime roots | Acknowledgement |
| ---: | ---: |
| 2 | 18 ms |
| 48 | 468 ms |
| 108 | 2,036 ms |
| 228 | 9,067 ms |
| 436 | 10,512 ms |

The persisted writable-root list reached 883 entries and contained recursively repeated .git/.codex suffixes.

After removing the redundant .git and .codex child rules, retaining "." = "write", and fully restarting Desktop, five turns on an existing lightly affected thread stayed at two runtime roots. Their acknowledgement times were 14, 24, 5, 8, and 5 ms, with no nested permission roots or composer timeout.

This adds evidence that recursive root expansion causes Desktop prompt-submission latency well before E2BIG and provides a causal connection to the root-count latency in #31838. Sanitized logs/session evidence is retained if maintainers need it.

TarjinderSingh · 13 days ago

Friendly follow-up for the maintainers: this regression remains reproducible on 0.147.0, including the independent reproduction above and the focused follow-up in #37632.

I checked the current public main branch through 7c194ff. The recent environment-selection refactors in #38423, #38461, and #38521 touch the relevant state flow, but I could not find a targeted guard or regression test for preventing derived permission paths from being reused as subsequent workspace roots.

Could you let us know whether a Desktop-side or internal fix is in progress? I’m happy to test a candidate build or provide additional sanitized root-count and timing diagnostics if useful.