Codex desktop app on Windows injects split writable roots, causing `apply_patch` to fail before patching workspace files, forcing agents to fallback to bypass the sandbox and write files using powershell

Open 💬 16 comments Opened Jun 30, 2026 by PurpleDevX
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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

26.623.70822

What subscription do you have?

Pro

What platform is your computer?

Microsoft Windows NT 10.0.26100.0 x64

What issue are you seeing?

The safe edit path (apply_patch) is unusable in Codex desktop app sessions on Windows. Agents have to fall back to shell-based file rewrites inside the project, which bypasses the sandbox and is less precise and more error-prone.

The apply_patch tool call fails when patching files inside the active workspace root. The failure happens before the target file is read or modified.

Observed Error (according to agent)

apply_patch verification failed: Failed to read file to update C:\git\foobar\apps\server\src\routes\sync.ts:
failed to prepare fs sandbox:
failed to prepare windows sandbox wrapper:
windows unelevated restricted-token sandbox cannot enforce split writable root sets directly;
refusing to run unsandboxed

Observed Behavior
The desktop app provides a managed sandbox profile with multiple writable roots (C:\git\foobar and C:\tmp). On Windows, apply_patch cannot construct/enforce that split-root sandbox using the unelevated restricted-token backend, so it refuses to run at all.

What steps can reproduce the bug?

  1. Ensure workspace-write sandbox mode is enabled.
  2. Create a new session in C:\git\foobar.
  3. Send prompt Create a test.txt file that says "hello world"
  4. Observe the file is created.
  5. Send prompt List the workspace roots added to this session, and also list all writable paths
  6. Observe the only workspace root is C:\git\foobar and writable paths are C:\git\foobar, C:\tmp, :tmpdir
  7. Send prompt Use the apply_patch tool to change "hello" in test.txt to "bye"
  8. Observe agent responds with I first tried apply_patch, but it failed because the Windows sandbox wrapper refused to run it in this restricted writable-root setup, so I made the same edit with PowerShell.

What is the expected behavior?

apply_patch should work for files inside the active writable workspace root, or the desktop app should not start Windows sessions with a sandbox shape that makes apply_patch unusable.

Additional information

The safe edit path (apply_patch) is unusable in Codex desktop app sessions on Windows. Agents have to fall back to shell-based file rewrites inside the project, which bypasses the sandbox and is less precise and more error-prone.

View original on GitHub ↗

16 Comments

github-actions[bot] contributor · 1 month ago

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

  • #30009

Powered by Codex Action

TheCrake · 1 month ago

Yeah, I'm still having this issue as of today. I've confirmed the issue is not present in the current IDE version of codex, only the windows app. I also checked older chat logs from a few weeks ago in codex and they were not having this issue, they were able to use apply_patch without errors.

cyhdzh · 1 month ago

I've got the same issue here when I use the codex VSCode extension.

peancor · 1 month ago

Adding some diagnostics from my Windows setup.

Environment:

  • Windows reports: Windows 10 Pro, 25H2, build 26200.8655, 64-bit.
  • PowerShell: 7.6.3.
  • Codex Desktop package: 26.623.11225.0, Status: Ok.
  • Internal Codex Desktop runtime: codex-cli 0.142.5.

What I tried:

  • Reinstalled Codex Desktop from Settings.
  • Restarted Codex.
  • Deleted Codex temporary state.
  • Tested across multiple repositories/workspaces.
  • Tried both Windows sandbox modes: unelevated and elevated.
  • Tried sandbox_private_desktop = false.
  • Tried excluding tmp roots with exclude_tmpdir_env_var = true and exclude_slash_tmp = true.

Observed behavior:

  • With sandbox = "unelevated":
  • Normal shell commands work.
  • apply_patch add works.
  • apply_patch update/delete fails with:

windows unelevated restricted-token sandbox cannot enforce split writable root sets directly; refusing to run unsandboxed

  • With sandbox = "elevated":
  • apply_patch add/update/delete works.
  • Normal shell commands fail before starting with:

CreateProcessAsUserW failed: 5

  • Setting sandbox_private_desktop = false did not change this.
my-short-circuits · 1 month ago

Wasted a bunch of tokens trying to get Sol to fix this until I found my way here. Please fix this..

rjgc80-cyber · 1 month ago

I can independently reproduce this in Codex Desktop on native Windows.

Configuration:

approval_policy = "on-request"
sandbox_mode = "workspace-write"

[windows]
sandbox = "unelevated"

[sandbox_workspace_write]
writable_roots = ["<workspace>"]

The Desktop UI showed a single workspace root, but the managed permission profile still injected other writable locations, including temporary/runtime paths and paths previously available to the task.

Minimal test:

*** Begin Patch
*** Add File: .codex-apply-patch-test.tmp
+apply_patch OK
*** End Patch

In one session, the patch failed before creation with:

apply_patch verification failed: Failed to read <workspace>\\.codex-apply-patch-test.tmp:
failed to prepare fs sandbox:
failed to prepare windows sandbox wrapper:
windows unelevated restricted-token sandbox cannot enforce split writable root sets directly;
refusing to run unsandboxed

Troubleshooting performed:

  • Reduced the visible workspace to one root.
  • Configured only one explicit writable_roots entry.
  • Restarted Codex.
  • Tested Codex launched normally and with "Run as administrator".
  • Running the packaged app as administrator did not change the internal restricted-token behavior.

A separate fresh-session test exhibited a closely related failure: the Add File patch succeeded, but deleting the same file through apply_patch failed with windows_sandbox_helper_unknown_error. The file could then be removed through another filesystem operation. This second symptom appears to match #31229.

The filename and patch body are ASCII-only and minimal. The failures occur during Windows sandbox preparation/ACL handling, before normal patch processing. This also encourages fallback to shell-based writes, bypassing the normal patch review workflow.

jkenter0528 · 1 month ago

I can independently reproduce this on Codex Desktop for Windows with the unelevated sandbox.

Environment:

  • Recent Codex Desktop build and bundled/standalone Codex CLI
  • Windows 11
  • Local workspace path redacted
  • No custom permission profile or user-configured writable roots
  • [windows] sandbox = "unelevated"

Repro:

  1. In a fresh Desktop task, built-in apply_patch Add File inside the workspace succeeds.
  2. Five consecutive built-in apply_patch Update File attempts against that existing file fail: 0/5.
  3. Built-in apply_patch Delete File fails with the same error.
  4. Ordinary sandboxed PowerShell works.
  5. Desktop displays a workspace root, normal temp root, and a per-task internal visualization root.

Exact error:

windows unelevated restricted-token sandbox cannot enforce split writable root sets directly; refusing to run unsandboxed

I also tested the standalone Codex CLI directly in workspace-write mode, without Desktop’s visualization root. Its effective writable roots were only:

<workspace>
<temporary directory>

Add File still succeeded, but the first existing-file Update failed with the identical error. This shows the visualization root is not necessary to trigger the issue; the normal workspace-plus-temp root set is sufficient.

I removed legacy custom workspace/skill/plugin roots and fully restarted Desktop. I also disabled the Visualize plugin. Neither changed the failure. This is therefore not caused by user-configured roots, stale skill roots, the temporary arg0 launcher, or Visualize alone.

Security concern: in Desktop, harmless Add File probes outside the displayed writable roots were unexpectedly created, while existing-file Update/Delete fail closed. That leaves apply_patch both unreliable and inconsistent with the declared boundary.

This appears to require a Codex Windows runtime fix. The unelevated restricted-token backend should support the effective split writable-root set, or the runtime should normalize/project its internal and temporary roots consistently before apply_patch is invoked. A local config workaround that removes normal temp access or broadens filesystem access would not be an acceptable solution.

PurpleDevX · 1 month ago

@fcoury-oai Heads up that your merged Codex PR #31138 which was intended to fix this either didn't get merged into the new unified ChatGPT app, or it didn't resolve the issue.

This bug still persists, and 5.6 wastes even more time on working around it constantly (I frequently see the thinking text say Planning a workaround for the sandbox apply_patch issue).

There is now also an additional even worse case which is blocking development of one of my projects completely. After extended development, some corner-case issue has been hit, where apply_patch cannot be used and agents refuse to work around it even in new sessions. I'm assuming this is due to the new ChatGPT app having a stricter system prompt. Agents simply say Blocked by the Codex patch helper: every apply_patch invocation fails because the WindowsApps executable returns “Access is denied,” including approved out-of-sandbox execution. No matter how much I've tried to get agents to bypass the sandbox restriction and use powershell for this project, they insist that their system prompt strictly prohibits bypassing the sandbox.

ameenah-syed · 1 month ago

Additional source-level evidence from codex-cli 0.143.0 and the current public main branch.

Observed source boundary

I reproduced the exact pre-file-access failure:

failed to prepare fs sandbox:
failed to prepare windows sandbox wrapper:
windows unelevated restricted-token sandbox cannot enforce split writable root sets directly;
refusing to run unsandboxed

The installed 0.143.0 binary maps to tag rust-v0.143.0, commit c4d748f586a84a3ed5b6aceb82e9a1db4abb1cda. The same refusal was still present when checked on public main at 78ba047bdae3db0342dee11d8d9ef5582fe8ce49.

The fail-closed check is in codex-rs/sandboxing/src/windows.rs, function resolve_windows_restricted_token_filesystem_overrides. It compares the compatibility projection writable roots with the requested split-policy roots and returns this diagnostic whenever the sets differ.

The lower Windows sandbox already has much of the required representation:

  • WindowsSandboxFilesystemOverrides.write_roots_override
  • wrapper support for --write-roots-json
  • one path-scoped capability SID per writable root in root_capability_sids
  • WRITE_RESTRICTED token creation with multiple restricting SIDs

However, the unelevated unified-exec branch does not forward WindowsSandboxSessionRequest.write_roots_override into spawn_windows_sandbox_session_legacy. The capture path in codex-rs/core/src/exec.rs similarly forwards the override only to the elevated backend.

Two related fail-closed/atomicity gaps are relevant to a complete fix:

  • canonical_existing in codex-rs/windows-sandbox-rs/src/setup.rs silently removes nonexistent roots.
  • apply_legacy_session_acl_rules in spawn_prep.rs suppresses several allow/deny ACL errors, and the setup helper logs missing write roots as skipped.

Reproduction detail

A named Add File probe succeeded once in the isolated official-source checkout. The immediately following built-in apply_patch Delete File operation failed during sandbox preparation with the split-root diagnostic, before reading the probe. Shell and Git access continuing to work does not disprove this because those operations use a different launch path.

Proposed enforcement contract

A complete launcher/policy fix should:

  1. Canonicalize and deduplicate the complete writable-root collection using Windows path semantics, including aliases, case, separators, UNC, and reparse points.
  2. Preserve every distinct root without widening access to a common ancestor or drive.
  3. Validate all roots and prepare all grants before child creation.
  4. Roll back partial ACL changes if any validation or grant fails.
  5. Preserve zero-root and single-root behavior.
  6. Never fall back to unrestricted execution, the first root only, or silently discarded roots.
  7. Keep undeclared parents, siblings, junction targets, and unrelated drives inaccessible.
  8. Produce a structured launch error naming the failed phase/root.

Windows CI should cover same-drive and cross-drive roots, spaces and Unicode, UNC, junction/reparse containment, alias deduplication, invalid-root partial failure and cleanup, shell plus built-in apply_patch writes in every declared root, and outside-root denial.

This is a root-cause analysis and proposed acceptance contract, not a claim that the platform fix has been implemented or validated.

homeofe · 1 month ago

Additional reproduction from Codex Desktop on Windows, observed on 2026-07-22.

Environment

  • Codex Desktop package: OpenAI.Codex_26.715.10079.0_x64__2p2nqsd0c76g0
  • Shell: PowerShell
  • Permission profile: managed workspace-write with restricted filesystem access
  • Effective writable roots included:
  • the selected workspace
  • a per-task Codex visualization directory
  • :slash_tmp
  • :tmpdir
  • The target file was an existing tracked file inside the selected writable workspace.

Primary failure: built-in apply_patch

The built-in patch tool failed before reading or modifying the target file:

apply_patch verification failed: Failed to read file to update <workspace>\local_model_tooling\toolcall.py:
failed to prepare fs sandbox:
failed to prepare windows sandbox wrapper:
windows unelevated restricted-token sandbox cannot enforce split writable root sets directly; refusing to run unsandboxed

This was not a malformed patch. The failure occurred while preparing the filesystem sandbox, before normal patch processing.

Approved escalation did not resolve it

The user explicitly approved running the operation outside the restricted sandbox. The generated wrapper resolved to:

%USERPROFILE%\.codex\tmp\arg0\<session>\apply_patch.bat

Its contents invoked:

"C:\Program Files\WindowsApps\OpenAI.Codex_26.715.10079.0_x64__2p2nqsd0c76g0\app\resources\codex.exe" --codex-run-as-apply-patch %*

Invoking that underlying packaged executable through the approved escalation path still failed at Windows process launch:

Program 'codex.exe' failed to run: Access is denied

The localized PowerShell error was Zugriff verweigert.

This second symptom matches #13959. That issue is closed as a duplicate, but current-version users have reported the same regression there. In this reproduction, the split-root sandbox refusal and the WindowsApps executable ACL failure occurred consecutively in the same task.

Control result

Using git apply with an equivalent unified diff succeeded in the same workspace and task. The requested implementation and subsequent tests also completed successfully. This confirms:

  • the workspace file was writable through an allowed tool path;
  • the patch content and repository state were valid;
  • user approval was not the missing requirement;
  • the failures are specific to the built-in Windows apply_patch sandbox/wrapper execution chain.

Expected behavior

apply_patch should update existing files within every declared writable root. If an approved out-of-sandbox retry is used, it should invoke an executable location that the approved PowerShell/tool process can actually execute, rather than the protected WindowsApps package resource path.

At minimum, the Desktop runtime should distinguish these two actionable failures:

  1. the unelevated backend cannot represent the effective split writable-root policy;
  2. the fallback wrapper targets a packaged executable that is not executable from the spawned process context.

A shell-based workaround exists, but it bypasses the normal patch tool workflow and should not be required for ordinary edits inside the selected workspace.

shalted · 1 month ago

Confirmed again on a newer Codex Desktop build with the same failure mode.

Environment:

  • Codex Desktop: 26.721.30844
  • Desktop-configured internal CLI/runtime: codex-cli 0.146.0-alpha.3
  • Separately installed PATH CLI: codex-cli 0.118.0 (not the runtime used by Desktop for this task)
  • Windows sandbox config: [windows] sandbox = "unelevated"
  • Active project is trusted
  • Managed writable roots are on separate volumes:
  • project workspace on E:\...
  • Codex-managed visualization workspace under C:\Users\<user>\.codex\visualizations\...

The target source file is writable (IsReadOnly=False), and its ACL grants Modify access to both the current account and CodexSandboxUsers. Nevertheless, apply_patch fails before modifying the target:

windows unelevated restricted-token sandbox cannot enforce split writable root sets directly;
refusing to run unsandboxed

This is especially confusing in Desktop because the second writable root is injected by Codex for visualization support; the user opened only the project workspace. The unrelated visualization root therefore prevents safe patching inside the valid project root.

Expected behavior: apply_patch should enforce and use the authorized target root even when another managed writable root is on a different volume, or Desktop should avoid passing an unsupported root topology to the unelevated Windows sandbox.

Impact: normal cross-folder/multi-root workflows become unusable, and agents either abandon edits or attempt less-safe shell rewrites. The failure is reproducible on this current Desktop build/internal runtime, so #30712 remains active in practice.

shalted · 1 month ago

Additional failure evidence from the same current Desktop environment: attempting the suggested approval/escalation path does not recover editing.

Observed sequence:

  1. Sandboxed apply_patch is refused because the managed profile contains split writable roots.
  2. The agent requests elevated/outside-sandbox execution.
  3. The elevated process then tries to access the packaged apply_patch.bat under the Codex WindowsApps installation.
  4. WindowsApps ACLs return Access is denied, so the packaged patch helper still cannot start.

This leaves a trusted and explicitly writable project root with no functioning built-in patch path: the unelevated wrapper rejects the root topology, while the escalated fallback cannot execute the packaged patch helper. The project root itself is not read-only and is not the denied target.

A valid direct git apply/shell edit may still work as a manual fallback, but that bypasses the intended built-in safe patch path and requires agents to construct patches correctly. The Desktop runtime should provide an escalation route that invokes an accessible helper or brokers the patch operation without relying on a WindowsApps path that elevated child processes cannot execute.

peancor · 1 month ago

Another update from Codex Desktop on Windows, observed on 2026-07-24.

Environment:

  • Codex Desktop: 26.721.31836
  • Permission mode selected in the Desktop UI: Full access

I had been using Full access as a last-resort workaround for the Windows sandbox problems already documented in this issue:

  • In elevated sandbox mode, normal commands could not start because CreateProcessAsUserW failed.
  • In unelevated sandbox mode, apply_patch could not reliably update existing files.
  • As neither sandbox mode provided a functional workflow, I knowingly accepted the risks of Full access.

Importantly, Full access had been working as expected for the past few weeks. During that time, Codex could carry out normal multi-step coding tasks without continuously requesting command approval. This behavior changed today, so it appears to be a recent regression rather than a configuration that never worked.

Starting today, even with Full access selected, Codex repeatedly asks me to approve commands—often roughly once per minute while an agent is working. This happens throughout ordinary multi-step coding tasks and requires constant supervision and interaction.

I have performed the usual troubleshooting steps, including completely restarting Codex Desktop and rebooting Windows. The behavior persists after both restarts.

Choosing the option to approve similar commands does not appear to solve the problem: Codex continues requesting approval for subsequent commands that are similar or equally innocuous.

As a result, all currently available modes are effectively impractical on my Windows installation:

  1. Elevated mode prevents normal process creation.
  2. Unelevated mode prevents reliable use of apply_patch.
  3. Full access now interrupts the workflow with continuous command-approval prompts, despite having worked correctly for the previous few weeks.

Full access is already a significant security compromise that I accepted only because the safer Windows modes were not working. If it still requires approval at almost every step, it no longer provides a usable fallback and makes Codex Desktop nearly unusable for autonomous coding tasks.

Confirmation for genuinely high-impact or destructive commands would be completely reasonable. The current behavior, however, can require approving dozens or even hundreds of harmless steps during ordinary work. This creates approval fatigue and may actually reduce safety: after being trained to approve a constant stream of routine commands, a user is more likely to approve a genuinely destructive command mechanically without noticing the risk.

Approval prompts are only an effective safety measure when they are exceptional and meaningful. When nearly every step requires approval, they become both a serious usability problem and a potential safety problem in themselves.

lackhoa · 1 month ago

Fresh reproduction on 2026-07-27 in Codex Desktop for Windows, package 26.721.4979.0 x64, managed workspace-write profile. Effective writable roots included the workspace, a per-task Codex visualization directory, :slash_tmp, and :tmpdir. Built-in apply_patch initially failed on an existing workspace file with: windows unelevated restricted-token sandbox cannot enforce split writable root sets directly; refusing to run unsandboxed. Retrying with a workspace-relative path failed identically, confirming the absolute Windows path was not the cause. In a later probe, apply_patch Add File inside the workspace succeeded, but the immediately following Delete File failed twice with the same split-root sandbox-preparation error. PowerShell removed the probe successfully. This confirms the failure remains present and can be operation-dependent/intermittent within one current Desktop task: Add may succeed while Update/Delete fail before reading the target. The fallback forces agents away from the required safe apply_patch workflow and into shell-based rewrites.

PurpleDevX · 1 month ago

Root cause found, with a config-only workaround that most people can use today and a one-line runtime fix for @fcoury-oai or another OpenAI dev to make.

Workaround

# ~/.codex/config.toml
[sandbox_workspace_write]
exclude_slash_tmp = true

On Windows this gives up nothing you actually had. The only access removed is <drive>:\tmp, which was never deliberately granted.

One comment above said they still had the issue with exclude_slash_tmp = true, so that user either has a different unrelated issue that surfaces with the same error, or didn't put the config option under [sandbox_workspace_write].

Root cause

The failure needs a writable-root set where the two sides of one comparison disagree. On Windows, /tmp is the only entry that can disagree.

  1. FileSystemSandboxPolicy::workspace_write (protocol/src/permissions.rs) pushes a SlashTmp write entry whenever exclude_slash_tmp is false (the default). There is no platform guard, so Windows profiles carry it too.
  1. The split policy resolves that entry in resolve_file_system_special_path via AbsolutePathBuf::from_absolute_path("/tmp"). /tmp is not absolute on Windows, so it absolutizes against the app server process's current drive and becomes <drive>:\tmp. It is kept if that directory exists.
  1. The legacy projection, SandboxPolicy::WorkspaceWrite::get_writable_roots_with_cwd (protocol/src/protocol.rs), gates /tmp behind cfg!(unix), so on Windows it never contributes a root.
  1. resolve_windows_restricted_token_filesystem_overrides (sandboxing/src/windows.rs) compares the two sets and fails closed when they differ.

Instrumenting that comparison and running a failing patch prints:

legacy = {"C:\\...\\workspace"}
split  = {"C:\\...\\workspace", "C:\\tmp"}
only_in_split = ["C:\\tmp"]

:tmpdir cannot cause this. Both sides resolve it from the TMPDIR env var, which is normally unset on Windows, so it contributes nothing to either set. That matches the writable list in the original report — C:\git\foobar, C:\tmp, :tmpdir — where /tmp appears resolved and :tmpdir appears unresolved.

Add File succeeds while Update/Delete fail because only the latter pre-read the target through the fs-sandbox helper. Hence Failed to read file to update ....

Why some people cannot reproduce it

The divergence exists only when <drive>:\tmp exists on the drive the app server runs from. Nothing in Codex creates it. Pointing the app server's process cwd at a drive with no \tmp makes the identical scenario pass with the stock Desktop binary.

Anyone who sees C:\tmp in their writable-roots list is by definition affected, since :slash_tmp only resolves when the directory exists.

Ruled out

Each tested against a build instrumented to dump both sets, with exclude_slash_tmp=true so /tmp could not mask the result. All produced identical sets and passed:

| candidate | result |
| --- | --- |
| extra writable root that exists | no divergence |
| extra writable root that does not exist | no divergence |
| multiple runtime workspace roots (the injected-root shape) | no divergence |
| workspace reached through an NTFS junction | no divergence |
| lowercase drive letter in cwd | no divergence |
| TMPDIR set explicitly | no divergence — present on both sides |

Multi-root configurations stay symmetric because ProjectRoots is materialized into concrete path entries before the check. So "split writable roots" in the sense of several roots was never the trigger; the trigger is one root that only one side produces.

Fix

         FileSystemSpecialPath::SlashTmp => {
+            // `/tmp` only names a real location on Unix. On Windows it is a
+            // drive-relative path, so absolutizing it silently produces
+            // `<current drive>:\tmp`, which the legacy `WorkspaceWrite`
+            // projection never yields because it gates `/tmp` on `cfg!(unix)`.
+            // Resolving it here would make the two writable-root sets disagree
+            // whenever that directory happens to exist.
+            if !cfg!(unix) {
+                return None;
+            }
             #[allow(clippy::expect_used)]
             let slash_tmp = AbsolutePathBuf::from_absolute_path("/tmp").expect("/tmp is absolute");
             if !slash_tmp.as_path().is_dir() {
                 return None;
             }
             Some(slash_tmp)
         }

resolve_file_system_special_path is the right place because it is the single choke point both sides go through. Fixing only workspace_write would miss profiles whose entries are supplied rather than derived.

cfg!(unix) leaves Unix behaviour byte-identical. Built from rust-v0.146.0-alpha.3.1 and from main (e8f0f64f20): the repro goes from
failing every time to passing 3/3, and codex-protocol (252), codex-sandboxing (37) and the codex-core Windows tests (54) stay green.

Aside: why this was hard to diagnose

app-server/src/lib.rs wraps state/sandbox failures with std::io::Error::other(format!("...: {err}")), which keeps only the outermost context and drops the underlying cause. Several unrelated failures surface as a single opaque line with no way to recover the real error without a source build.

bshih · 27 days ago

Thanks to https://github.com/openai/codex/issues/30712#issuecomment-5098495052, I was able to finally chase down the fix. I also initially thought it was the .visualizations writable root, but it was a red herring. I independently confirmed the /tmp policy-mismatch diagnosis and found an additional Codex Desktop configuration-precedence issue that explains why the suggested workaround may initially appear ineffective.

Environment:

  • Native Windows Codex Desktop 26.721.11231
  • [windows] sandbox = "unelevated"
  • C:\tmp exists
  • Actual Windows TEMP/TMP point to the user-profile temp directory
  • TMPDIR is unset

Original behavior using native apply_patch:

  • Create File: succeeds
  • Update File: fails
  • Delete File: fails

Exact error:

windows unelevated restricted-token sandbox cannot enforce split writable root sets directly; refusing to run unsandboxed

The per-task .codex\visualizations\... writable root is not the cause. After fixing the /tmp mismatch, tasks retained one or more visualization roots and native create/update/delete all succeeded.

I first added only:

[sandbox_workspace_write]
exclude_slash_tmp = true

After fully restarting Desktop and creating a fresh task, the effective recorded policy still contained:

exclude_slash_tmp = false
write: :slash_tmp

Update and delete therefore continued failing with the same error. The global setting existed but was not active because Desktop was selecting its newer managed permission-profile path. OpenAI’s documentation notes that permission profiles do not compose with the older sandbox_mode / [sandbox_workspace_write] configuration path.

The working global configuration was:

sandbox_mode = "workspace-write"

[sandbox_workspace_write]
exclude_slash_tmp = true

[windows]
sandbox = "unelevated"

After another full restart, a completely fresh task—with no project-level .codex/config.toml—recorded:

sandbox_policy.type = workspace-write
sandbox_policy.exclude_slash_tmp = true
sandbox_policy.exclude_tmpdir_env_var = false

The effective permissions no longer contained :slash_tmp. The workspace, :tmpdir, and injected visualization roots remained writable.

Three separate native apply_patch calls then:

  1. Created a disposable file.
  2. Updated the existing file.
  3. Deleted the file.

All three succeeded. No shell fallback was used and no probe remained.

This suggests two related product fixes:

  1. Treat SlashTmp as Unix-only when resolving filesystem special paths on Windows.
  2. Ensure Desktop’s managed permission-profile path either honors sandbox_workspace_write.exclude_slash_tmp or clearly communicates that the setting is inactive unless sandbox_mode = "workspace-write" selects the older configuration path.

Deleting C:\tmp would also make the mismatched root disappear, but that is brittle because another tool can recreate the directory. The explicit exclusion is the durable workaround.