Python UV fails in Codex
Resolved 💬 60 comments Opened Jul 3, 2025 by corrylc Closed Jan 10, 2026
💡 Likely answer: A maintainer (oai-ragona, contributor)
responded on this thread — see the highlighted reply below.
What version of Codex is running?
codex-cli 0.2.0
Which model were you using?
codex-mini-latest
What platform is your computer?
Darwin 24.5.0 arm64 arm
What steps can reproduce the bug?
Start codex in environment using uv and tell it to run pre-commit or many other tools. All fail with sandbox violations.
What is the expected behavior?
uv runs normally
What do you see instead?
Not permitted errors, due to sandboxing restrictions
Additional information
I tried adding the ~/.cache/uv directory to writable roots, but it had no apparent effect.
This is similar to the issues I saw with NPM when on the fully YOLO mode, but I was able to avoid them using auto-edit mode there. In the rust version it seems that all modes produce the same sandboxing errors, making the tool functionally unusable in the present state.
60 Comments
Looks like this is indeed related to the Seatbelt sandboxing. On my machine at least though, it doesn't want
~/.cache/uv, it wants~/Library/Caches/uv-- though allowing that doesn't fix it either.Dang okay that was a bit of a journey. I did get it working with:
The lingering question I have is which parts of the env are requiring
shell_environment_policy.inherit=all, and what the minimal subset there is.I gave the modified sandbox settings a try, and it doesn't appear to help on my box.
uvremains nearly impossible to use within codex, for no clear reason.Ok, so setting UV_CACHE_DIR to be within the repo resolves the issue, though it is ergonomically unpleasant to maintain.
Something about UV's interaction with its cache directory is quite poisonous to the sandboxing...
Ok, the only way I can determine to fix Codex for this issue is:
Attempting to set the same path via
codex -c "sandbox.writable_roots=['/Users/corry/.cache/uv']"is not effective.Attempting to set writable_roots in general seems fraught, perhaps completely broken? I can't tell why the equivalent config setting is so ineffective, as compared to modifying the seatbelt policy...
doesn't seem to work for me. At least on most recent codex release
0.39.0installed via brewThe better way seems to be: https://github.com/openai/codex/issues/2444 however, it doesn't work for me either:
with this config:
I still get:
Probably because
.gitand docs mention that git folders are implicitly read-only without a way to override it.Wonder if anyone found a consistent way to use codex with python project relying on uv
Modifying the sandbox policy itself and recompiling is the only complete fix I have found. I don't understand the sandbox enough to say why Codex's own templating is failing.
ah, I missed the part you've tried that setting in your comment.
It seems like the setting does work to some extent. I had multi-layered issue with brew shellenv (calls
/bin/psif you are not passing shell name explicitly, which my profile files did), then mise (still wondering why on earth mise kicks in during uv commands, even if I use mise managed python), then uv failing.I think that at least
misestopped producing errors when I've added it's cache to the setting list. So it kinda works. And the path that causes the error in uv also chagned, from root cache folder to that.gitsubfolder in the message. So I suspect.gitis implicitly added as restricted somewhere in the code. Maybe worth asking codex to search through codex codebase to find the exact place and open a PR ;-)@mishamsk are you explicitly setting your
sandbox_mode? Per the docs:We have https://github.com/openai/codex/pull/3341 to make this more intuitive, which will land in the next day or two. Until then, setting
sandbox_modeshould force the setting to take effect.@dylan-hurd-oai Not in the config, but I've set it for the given project when asked by TUI. Isn't it supposed to be per-project rather than a global setting? What if I do not want codex to be able to write in some projects but still be able to work with uv etc?
@dylan-hurd-oai Are you able to run a command like the following in a project?
I cannot get this to work by any means in the sandbox, except my code patch.
I am curious if this works for you (on a mac). I really do want to use codex more, but the persistent failure of
uvis deeply frustrating.If that command does work, I would be curious if you are using brew, as that may well play a part here as well, though I am not certain.
@corrylc can you try
codex -s workspace-write -c "sandbox_workspace_write.writable_roots=['/Users/corry/.cache/uv']"?I've tried it, or something like it, along the way. But I will try it again in the morning and report back 👍
I also face the same issue on my machine. I directly installed the binaries from the GitHub release. Here is the output I get:
Just to be certain, ran without any writable roots & with that git folder directly:
seems to stumble at the same path
writeable_roots will not work for you with debug seatbelt, AFAIK - https://github.com/openai/codex/issues/4151
@dylan-hurd-oai I tried
codex -s workspace-write -c "sandbox.writable_roots=['/Users/corry/.cache/uv']"and got the usual error:@corrylc sorry, I should have checked your command more carefully. Per the config docs:
We definitely want to make configuration a better experience, sorry for the confusion here!
@dylan-hurd-oai Well, there is progress. I tried something like that in the past and it didn't work.
But now at least it produces a _different_ error:
Will play around with this more. Are you using
uvinstalled from brew, or directly?No matter the
uvinstallation source, one quick workaround is to forceUV_NO_SYNC.``
UV_NO_SYNC=1 codex exec -c "sandbox_workspace_write.writable_roots=['$HOME/.cache/']" --sandbox workspace-write "im testing something, run uv run python --version"``Tradeoff is that your env will be effectively frozen.
---
But this seems like a never ending battle. I'm running into another problem where uv pre-commit hooks calls
os.sysconf('SC_ARG_MAX')which is a kernel call blocked by sandbox.I do not understand why aren't the calls originating from workdir exempt from this if I trust it?
@dylan-hurd-oai ok, the NULL panic appears to be resolvable with the following patch (based substantially on GPT-5 guidance). I am not sure _why_ this is specific to my environment though, or why exactly this fixes it.
The patch above is on codex/main, with no other patches. So this is definitely in a much better state.
I don't know remotely enough about seatbelt to say if that change is "safe" so hopefully someone on your side does...
Note that with this fix I very shortly ran into the issue in #2486 (which had PR #2494 to fix it, that was inexplicably closed).
So I added that fix to my seatbelt policy as well, and things are working nicely.
To share, my current diff from v0.41.0 is:
None of the above options helped with this problem.
I have been using the patch above, applied to 0.41 and 0.42, for the last several days of heavy use on a python project and it has worked flawlessly. I have kept the sandbox enabled throughout without issue.
Specifically, I have been able to use
uv,pre-commit, and other python tooling without any errors induced by codex.@maxbaluev It may help if you provided some additional details as to what you tried, and what issue(s) you are seeing.
Tested the fix suggested above and it works.
In case it helps anyone else, I've further added the following to my .zshrc:
This serves as a default wrapper so that I can simply run
codex(with optional args) anywhere.Having the same issue, which significantly impacts Codex performance for uv-based Python projects.
@dylan-hurd-oai Do you see any reason not to integrate the patch from corrylc above? I'd be happy to open a PR
FYI I am seeing a semi-adjacent issue where Codex is _extremely_ overeager to assume that all errors are sandbox errors, even when they obviously cannot be. I am tracking this in #4859
I'm still facing an issue with this. if i run it with the workspace write sandbox command codex just hangs while running the uv command. i am currently on 0.46.0 as well. without the workspace args here's what i get:
Ran uv run pytest
└ failed in sandbox: error: Can't create the symlink for multishells at "/run/user/1000/fnm_multishells/2468830_1760034852118".
Maybe there are some issues with permissions for the directory? Permission denied (os error 13)
error: failed to open file
/home/user/.cache/uv/sdists-v9/.git: Permission denied (os error 13)Seems to be working on 0.47.0 with workspace_roots set via config. No need to pass anything over to cli.
I still get weird errors from mise that I use to manage python versions
mise ERROR Operation not permittedbut surprisingly it doesn't prevent uv/python from working....The following in the config seems to quiet mise when running uv:
although
mise doctorpanics when executed from codex ;-) Without the share folder added to permissions it errors but works... sandbox + Rust - no ❤️ apparently.But at least uv/python are usable now!
uv version: 0.9.4
codex cli version: 0.47.0
os: macOS 26.0.1
i am unable to run tests using
uv run pytestwith the following config on codex 0.47.0:commenting out the lines with
.cache/uvcauses codex to ask for permissions to run the command and then it succeeds.if helpful, here are example sessions:
"/Users/adam/.cache/uv"writable_root entry"/Users/adam/.cache/uv"writable_root entry.Ok. I swear it worked yesterday, but today I am getting the same panics as @adamalix even though I do not believe uv has been updated in the last 24 hours... I am on MacOS 15.7.1
Same issue - but with poetry instead of uv.
config.toml
"Try running poetry install"
cabal (Haskell package manager) has similar problems with its caches. The only way I've found around it is to treat WSL2 as the sandbox itself and to turn of the file sandboxing. Adding the cabal cache directories only helps slightly as the sandbox does not seem to cope with cross directory renames even within the workspace.
As it happens, @nornagon-openai's change in #5980 will fix the issue for uv, but only when networking is enabled, as it covers the key flag.
The secondary patch for pre-commit would still not be covered.
@nornagon-openai Any chance the sandbox can be tweaked a bit more to resolve the issue with
uvin all cases?(nice fix by the way, I tried to figure out the sandbox policies for
ghand couldn't get it working)Thanks @corrylc! I can confirm uv is working for me using codex 0.56.0 and
Not sure somebody else reported this on the uv side already, but I reported a seatbelt related error over there:
https://github.com/astral-sh/uv/issues/16664
For those who are interested in tracking this
The core issue has been fixed, so I'm going to close this issue. If you see any further problems with
uv, please open a fresh issue.@etraut-openai The core issue has not been fixed. There is no reason that
uvshould require networking to be enabled, and it only happens to work in that mode as the internet sandbox policy includes the one policy element thatuvrequires.uvstill fails in Codex under default configuration, and the fix remains the same (adding the single line to the seatbelt policy).uv initialises an http client to read from pypi, which panics if it can't read the network configuration and why it needs the network sandbox policy.
There is a fix for the panic, which might help for uv commands that don't use pypi when it makes its way into uv see https://github.com/mullvad/system-configuration-rs/issues/71.
Although any uv commands that need to use pypi will still require network access.
@etraut-openai Please reopen the issue, codex still fails in most of the UV use cases.
Reopening as requested.
Hey, guys. I'm also hitting the
~/.cache/uv/sdists-v9/.git: Permission denied (os error 13)failure on Linux.In the end, I realized that I basically don't need Codex to
uv runin the sandbox. Instead,source .venv/bin/activateis very enough.The relevant part of my global
AGENTS.mdlooks like this:I tried this on my Mac. Didn't solve the issue. Just constantly fighting sandboxing issues with codex.
sandbox_mode = "workspace-write"
[sandbox_workspace_write]
network_access = true
writable_roots = [
"/Users/itsame/.cache/uv",
]
At one time I had the homebrew cache in there as well, didn't make any difference.
same issue
I'm now getting a different error with codex version 0.71.0 on latest macOS.
Sandboxed (sandbox_mode = "workspace-write", writable_roots explicitly set):
(not sure what the referenced user
runneris above; that is not the user I'm logged in and there is no user "runner" on the system AFAIK -- at least visible on disk)when running with
codex -s danger-full-accessit works fine:Improvements have been made to both uv and Codex to improve interoperability of the two.
I did some testing with the latest version of both, and it's working well for me. When I run a
uvcommand within the Codex sandbox that requires a write to uv's cache, it asks for approval. Once I approve, it successfully runs the command. Subsequent invocations that don't require a cache update run without the need for approval.If you're still experiencing problems uv in Codex, please let us know. In particular, it would be helpful if you could use the
/feedbackslash command to upload your logs and session details and then post the thread ID here so we can diagnose.@etraut-openai Thanks for the update. I gave it a try.
With Codex v0.79.0, and with sandbox internet access disabled, use of
uvfails instantly. Reported in feedback019b9f9d-d3cf-7973-912e-ccb09e104bb1.With sandbox internet access enabled, and with the
uvcache directories added to write access, it does work as expected. But this is more or less an accidental fix, and there isn't any reason thatuvshould only work when the sandbox has internet access enabled.I would guess that you have internet access enabled with
sandbox_workspace_write.network_access=true, cloaking the underlying issue.Specifically,
uvneeds the following sandbox policy:This policy is not present in the base Codex policy, but was added in the internet access mix-in.
@corrylc, thanks. I did my testing with the default sandbox policies on MacOS: no writes outside of the project directory and no network access.
Are you using the latest version of uv? I'm using 0.9.22. I looked in the session data that you uploaded (thanks!), and it looks like uv panic'ed. That's a behavior that occurred with older versions of uv. I tried the exact same prompt that you used in your session, and it worked fine for me. I received the following allow dialog from Codex:
<img width="1634" height="314" alt="Image" src="https://github.com/user-attachments/assets/07003642-e56c-4bb9-93b5-f2c95be78ebb" />
Once I approved (option 1), it ran without a problem.
I am using
uv 0.9.22 (Homebrew 2026-01-06), so both Codex and UV are the newest available.One thing I would note is that
uv run python --versionshould not require running with elevated access (outside the sandbox) or cache write access, as it is a readonly command, so the prompt you see is unexpected and unnecessary. Obviously if you say yes to run it outside the sandbox, it will succeed, but that shouldn't be required.So if you answer "no" to that prompt and/or instruct Codex to run the command in the sandbox, do you see it panic?
When I run
uv, as in the feedback I reported, Codex did not prompt me like yours did. It simply ran the command and panic'ed.That depends on uv's implementation. If it writes to a location disallowed by the sandbox policy, it will trigger an elevated access allow prompt.
No, I don't see it panic. If I answer "no", then
uvisn't run again, so there's no opportunity for it to panic. And the original prompt is the result of Codex attempting to run the command in the sandbox, and it doesn't panic in that case either.Is it possible that you have multiple copies of uv installed on your system? I wonder if the wrong (older) one is being invoked within the sandbox? If you run
!where uvin Codex, does it show the location that you expect?What sandbox / approval settings do you have configured in your
config.toml? Which model are you using?Right, so there are two things blocking UV from operating normally:
UV requires write access to the UV cache for unclear reasons, which is resolved by adding the cache as a writable root (my config below). If this permission is granted, the following error appears:
This error is readily resolved with the following config:
Once that config is installed, UV then runs into an extremely opaque error:
Which can be resolved by either enabling network access in Codex or modifying Codex's code to add the seatbelt policy I shared above.
To clarify, if you answer no and then tell codex to run it without elevated permissions (i.e. inside the sandbox) I would expect you to see the same error I see. Or to put it another way, do you have a case where the command was definitely run _inside_ the sandbox without erroring?
For me, assuming the
writable_rootscontains the cache directory then any invocation ofuv run python --versioninside the sandbox fails.I checked, and the versions are all correct. I also asked codex to run
uv --versionand the version was 0.9.22 as well.To double check, I used a copy of
uvinstalled within the repo, and uploaded a feedback for it, but the issue is the same:019b9fe6-cf07-7960-8919-9a3756fa63feShared above. For model I am using
gpt-5.1-codex-mini mediumfor this testing, but I typically use better models (the issue is independent of the model though).IME the model proactively asking to run a command outside the sandbox is new and unpredictable. And running
uvcommands outside the sandbox should work assuming writable roots is configured.So my complete reproduction case:
/Users/$USER/.cache/uvto your sandbox writable roots. Alternately use environmental variables to keep the uv cache inside your workspace.uv run python --versionand report the output.I commented out following (which I added myself manually when trying to fix the issue based on recommendations earlier in this issue):
And when I restarted codex (v0.79.0), it first failed to run uv but then asked for permission and after allowing it in the TUI, it now works perfectly 🎉
Yes, I think it works fine now if you use the default sandbox policy.
I'm able to repro a panic when I modify the sandbox policy to allow writes to
/Users/$USER/.cache/uv(thanks @corrylc for the repro steps). I've asked Codex to look at uv's source code to try to figure out the problem.I asked two questions:
Question: Why does uv require write access to its cache directory when running a simple command like
uv run python --version?Codex's Answer: uv run always bootstraps the cache before doing anything else. In the ProjectCommand::Run path it calls cache.init()
Question: What is the likely cause of the uv's panic when Codex's sandbox policy is modified to enable writes to the cache directory?
Codex's Answer: The panic you see comes from the wrapper thread that runs uv’s Tokio runtime. In main uv spawns a helper thread for run(cli) and does .join().expect("Tokio executor failed, was there a panic?") (lib.rs lines ~2611‑2614). That expect only triggers when the inner thread panics. Given your log reaches the VIRTUAL_ENV … ignored warning, the next fallible work is cache/environment setup (creating/locking files in ~/.cache/uv and temp dirs such as builds-v0 in lib.rs and environment.rs). If the sandbox still blocks some of those filesystem/locking operations or thread creation for the blocking lock helpers, they can panic inside the runtime, which bubbles out as the generic “Tokio executor failed” message. Running with RUST_BACKTRACE=1 or UV_LOG=debug would show the exact failing operation.
I'm in contact with the maintainers of uv at Astral. I'll see if they can provide some assistance here.
@etraut-openai Happy to see the repro worked! 🎉
Agreed that a readonly(ish) command shouldn't particularly need write access to the cache, though that can be worked around by defining
UV_CACHE_DIRinside the workspace, in a pinch.To the panic, I was never quite sure why it happens, but the
com.apple.SystemConfiguration.configdsandbox policy definitively fixes it. Though of course if Astral can remove the need for that permission, all the better.The panic should be resolved by https://github.com/mullvad/system-configuration-rs/pull/59 — it looks like we lost track of that dependency upgrade over the holidays so I'll get that into the next uv release.
edit: Unfortunately we're blocked by https://github.com/hyperium/hyper-util/pull/256. We're tracking this in https://github.com/astral-sh/uv/issues/16916
Thanks @zanieb!
uvis now working correctly with the default Codex sandbox rules, and a future release of uv will address the panic when custom sandbox rules are in effect.Is this working for other people now? I'm still getting sandbox errors on macOS Tahoe:
And same on Ubuntu Linux:
<details>
<summary>Versions and config</summary>
</details>
I also tried deleting
~/.cache/uv, and on macOS downgrading touv0.9.24 (Jan 9 release), but neither of those helped.Update: See also https://github.com/astral-sh/uv/issues/16820#issuecomment-3973110432.*
Workaround
export UV_CACHE_DIR=/tmp/uv-cacheto my.bashrcto change the cache from~/.cache/uvto/tmp(which the Codex sandbox is happy to write to) makes it work fine, provided that I've previously runuv syncso that everything is downloaded.~~export UV_TOOL_DIR=/tmp/uv-toolssimilarly stopsuvxfrom locking~/.local/share/uv/tools. Note that based on a cursory read, this might break tools installed viauv tool installif your/tmpever gets cleaned out. If that happens, you might have to reinstall them by rerunninguv tool install. If you only useuvx, you should be fine though --uvxby itself doesn't actually put anything in the directory, it just locks it to check for existing installs.~~/tmp.Instead, I'm now adding this in my
~/.codex/config.toml:``
toml
``[sandbox_workspace_write]
writable_roots = ["~/.cache/uv", "~/.local/share/uv/tools"]
If polluting the system prompt with references to uv directories is a concern, also add this at the top level of
~/.codex/config.toml:``
toml
``include_permissions_instructions = false # added in v0.119.0-alpha.9
This doesn't yet do anything in the current stable release, but should start working in the next release.
~/.codex/config.tomlhelps stopuvfrom hitting the network to check for updates while it's inside the sandbox:``
toml
``[shell_environment_policy.set]
UV_OFFLINE = "1"
Thanks @joliss -- with setting my config.toml to have this:
And upgrading uv to 0.10.7, I was able to get it to work (_leaving the unrelated DJANGO module config here just in case it solves anyone else's problem, esp. with JetBrains/PyCharm AI Agent. lol_)
This allowed me to set up a rule in my project's ~/.codex/rules/default.rules allowing uv to run:
This requires "ruff" in pyproject.toml / requirements.txt -- which is fine for this project, but for other projects where I can't mess with the requirements/directories, I wasn't able to run
uvx ruff check MY_PROJECTbecause of a different cache problem:Since I know the great folks with astral are looking at this thread, maybe there's a fix for that too.
@mscuthbert I think you can fix the error in
~/.local/share/uv/toolsby settingUV_TOOL_DIR-- see my edited workaround above.