Linux sandbox fails with "bwrap: Can't create file ... Is a directory" when protected workspace path is a symlinked directory

Resolved 💬 0 comments Opened Mar 25, 2026 by Harag Closed Apr 21, 2026

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?

  1. 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

  1. Start Codex CLI in that workspace with a sandboxed mode that uses the Linux bubblewrap backend.
  1. Run any normal shell command through Codex, for example:

pwd
rg --files
sed -n '1,20p' some-file
git status

  1. Observe that the command fails before execution with:

bwrap: Can't create file at .../.agents: Is a directory

  1. Switch to danger-full-access, or remove/rename the root .agents symlink, 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:

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/null mask 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.

View original on GitHub ↗