apply_patch fails when writable roots are symlinked (bwrap bind error)

Resolved 💬 10 comments Opened Mar 14, 2026 by rebroad Closed Mar 18, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

When ~/.codex is a symlink to another partition, apply_patch fails in the sandbox. This started after the memories feature was introduced (it appears to create/use ~/.codex/memories).

Version

codex v0.115.0-alpha.19

Repro

  1. Make ~/.codex a symlink to another partition (e.g. /mnt/p8/@home/rebroad/.codex).
  2. Run any apply_patch operation.

Actual

bwrap errors out during sandbox setup:

bwrap: Can't mkdir /home/rebroad/.codex/memories: No such file or directory

Earlier it also failed with:

bwrap: Can't bind mount /oldroot/mnt/p8/@home/rebroad/SunOS on /newroot/home/rebroad/SunOS: Unable to mount source on destination: No such file or directory

Expected

apply_patch should work regardless of whether ~/.codex is a symlink. The sandbox setup should resolve symlinks or create needed paths inside the sandbox appropriately.

Notes

This appears to have regressed after the new memories feature that uses ~/.codex/memories.
The commit that introduced create_dir_all(&memories_root) and added the memories root to workspace-write is:
f72ab43fd193b31208cd3c306293b1b71a52a709 (2026-03-04 13:00:26 +0000, "feat: memories in workspace write (#13467)").

There may also be a related regression in Linux sandboxing around symlink handling in bubblewrap:
774965f1e8691f1a0568fb801f24b15553e5e6cd (2026-03-12 10:56:32 -0700, "fix: preserve split filesystem semantics in linux sandbox (#14173)").
That change added explicit symlink detection in bwrap mount setup, which may cause symlinked writable roots (like ~/.codex) to be masked.

View original on GitHub ↗

10 Comments

github-actions[bot] contributor · 4 months ago

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

  • #14261
  • #13635
  • #14672

Powered by Codex Action

etraut-openai contributor · 4 months ago

I think this is a duplicate of #13635

rebroad · 4 months ago
I think this is a duplicate of #13635

it is, but that one is closed, and this is still an issue

etraut-openai contributor · 4 months ago

Ah, good point. Reopening this one.

yitoli-c · 4 months ago

To give some example impacts from this error: #14261, namely:

  1. users wary of "full-access" mode will see codex stuck in trying to fix the observed error, or spent many turns trying to use alternative approaches to apply patch
  2. with multi_agent, even if main agent has "full-access", sub-agent by default does not have "full-access", so it can stuck in the loop trying to fix the observed apply_patch error first, and gave up the assigned task eventually.

Symlink ~/.codex seems to be an important common factor here. Unlink ~/.codex is not an option due to disk quota setup we have.

rebroad · 4 months ago

confirmed still an issue on v0.115.0-alpha.23

rebroad · 4 months ago

I am working on a fix for this. The problem is when the codex binary is being accessed via a symlink. bwrap then can't find it within it's imaginary world and so everything fails given it can't find itself/codex. Proposed solution is to capture arg0 to an environment variable near the beginning of main, and pass that so that bwrap can substitute the self it cannot find with a self it can find.

I now have a fix for this. It fixed a number of scenarios, such as the codex binary being within a symlink structure, and also a workspace folder being a symlink. All these scenarios need special treatment (e.g. if the workspace is a symlink, then the symlink target needs to be read/write and bwrap should NOT try to mount onto the symlink path).

rebroad · 4 months ago

@yitoli-c @etraut-openai I have created a fix for this at https://github.com/rebroad/codex/tree/fix-symlink-issues

Context / Prior Work

This fix intentionally diverges from the policy normalization introduced in
commit 9060dc7557848feb80a0fca612b9b1037c2ec217 (“fix symlinked writable roots
in sandbox policies”, #14674). That change canonicalized effective roots to
their resolved paths, which is correct in isolation, but in Linux sandboxing it
can yield paths that are not visible inside the bwrap namespace. The result is
bind failures in symlinked workspaces.

This fix keeps policy inputs on user-visible logical paths and explicitly binds
symlink targets in bwrap, so the namespace exposure remains deliberate and
consistent with what the user sees.

SproutSeeds · 4 months ago

normalize_permission_paths in codex-rs/core/src/sandboxing/mod.rs still canonicalizes writable roots before Linux sandbox mount construction.

  • bwrap later builds bind mounts from those effective roots
  • when ~/.codex or the workspace is reached through a logical symlink, the namespace can lose the user-visible path that later mount logic expects
  • the current self-exe path also still depends on a launch path shape that symlinked codex binaries can break
  • that failure mode is in Linux sandbox path shaping and self-exe resolution, not the apply_patch parser

I did not rerun the full Linux bwrap repro on a Rust-capable Linux host in this pass.

The failure mode is in Linux sandbox path shaping and self-exe resolution under symlinked paths.
Preserve user-visible logical paths in policy, bind symlink targets explicitly in bwrap, and carry the launched self-exe path through the sandbox entrypoint.

rebroad · 4 months ago

Fixed by #14849 thank you!