-
Notifications
You must be signed in to change notification settings - Fork 10.2k
Linux sandbox fails with "bwrap: Can't create file ... Is a directory" when protected workspace path is a symlinked directory #15725
Description
What version of Codex CLI is running?
codex-cli 0.116.0
What subscription do you have?
Pro
Which model were you using?
gpt-5.4
What platform is your computer?
Linux 6.17.0-19-generic x86_64 GNU/Linux
What terminal emulator and version are you using (if applicable)?
bash on Ubuntu Linux
What issue are you seeing?
In my repro, the workspace root contains:
.agents -> some-folder/.agents
When Codex runs a normal shell tool in sandboxed mode, bubblewrap fails immediately with:
bwrap: Can't create file at .../.agents: Is a directory
This is not a normal permission denial. The problem is that the Linux sandbox is treating the protected alias like a file path and tries to mask it with a file-style bind, but the
alias resolves to a directory. bubblewrap rejects that path-type mismatch before the user command runs.
This may be in the same general Linux/bwrap/workspace-write area as other sandbox failures, but the exact symptom here is different from namespace creation failures: this repro is
specifically an Is a directory error caused by a symlinked directory alias at the workspace root.
What steps can reproduce the bug?
-
On Linux, create a workspace where the root contains a symlink to a directory, for example:
mkdir -p some-folder/.agents
ln -s some-folder/.agents .agents -
Start Codex CLI in that workspace with a sandboxed mode that uses the Linux bubblewrap backend.
-
Run any normal shell command through Codex, for example:
pwd
rg --files
sed -n '1,20p' some-file
git status -
Observe that the command fails before execution with:
bwrap: Can't create file at .../.agents: Is a directory -
Switch to danger-full-access, or remove/rename the root
.agentssymlink, and the same command succeeds.
What is the expected behavior?
Sandboxed shell execution should still work when a protected workspace-root alias is a symlink to a directory.
If Codex needs to make that path read-only/unreadable inside bubblewrap, it should preserve the path type and bind the resolved directory appropriately instead of trying to file-mask
the alias. Routine shell commands should not fail before execution because a protected alias points to a directory.
Additional information
I tested a local fix and it resolves the repro.
Tested diff:
- Fork branch: https://github.com/Harag/codex/tree/local/bwrap-symlink-directory-fix
- Commit: a143a5d
- Repo: https://github.com/Harag/codex.git
Local patch artifacts:
- /tmp/codex-bwrap-symlink-directory-fix.patch
- /tmp/codex-bwrap-symlink-directory-fix-verification.txt
Patch summary:
- Detect when a protected alias resolves to an existing directory.
- In that case, do not use a file-style
/dev/nullmask on the alias. - Instead, bind the resolved directory path in a way that preserves directory semantics.
Validation performed:
- Rust tests passed for the new sandbox cases.
- Direct bubblewrap repro confirmed the old behavior fails with
Is a directory. - Direct bubblewrap verification confirmed the patched behavior keeps the directory readable while preventing writes through the protected alias.
- The installed Codex wrapper was smoke-tested successfully after replacing the vendored binary with the locally built patched binary.