Commands under user profile still wrap in `bash -lc` (RE PR: #1678)
What version of Codex is running?
latest on main.
Which model were you using?
o3
What platform is your computer?
Darwin 25.0.0 arm64 arm
What steps can reproduce the bug?
- Enable the
experimental_use_profileflag inShellEnvironmentPolicy. - Run a command (my fave, "What is the current output of $PATH?")
- Notice that the shell function call is wrapped by the user's shell, but that the _command_ is wrapped in
bash -lc. - Notice that the output is very likely not correct due to it returning amended path due to contents of
/etc/profile-- particularly the way thatpath_helperis invoked.
What is the expected behavior?
When using experimental_use_profile, I would expect that the environment/setup of the user's profile would be used. Instead, pushing every command through a bash -lc wrapper makes the use of the user's shell kind of pointless?
(but i may not be correct: @pakrym-oai / @bolinfest - would appreciate your comments here)
What do you see instead?
- Notice that the shell function call is wrapped by the user's shell, but that the _command_ is wrapped in
bash -lc. - Notice that the output is very likely not correct due to it returning amended path due to contents of
/etc/profile-- particularly the way thatpath_helperis invoked.
Additional information
I'm not 100% sure of the intended behavior of this feature, initiated by PR #1678 .
However, I think the intention is to allow the user's shell to take over, rather than the previous constrained approach. I would think then that seatbelt (or others) would step in to keep the session safe.
Instead, the models are pretty insistent in returning every command wrapped in bash -lc. This definitely violates that previous intention.
I have done some exploration of what it would look like to get rid of the bash wrap, which you can see here: https://github.com/imajes/codex/pull/1/files -- however this is definitely not merge ready or anything, and would need guidance as to whether or not it makes sense.
12 Comments
@imajes Do you have something in your
~/.bashrcthat overwritesPATHrather than amends to it?I would expect that running
bashfrom an existingzshshell should inherit whatever environment variables are already there...For example, I expect you have some number of shell scripts that start with#!/bin/bashthat probably work, right?What I think might be another issue is https://github.com/openai/codex/blob/main/codex-rs/config.md#shell_environment_policy.
As noted on https://github.com/openai/codex/issues/1249, I'm not convinced I got this right and I'm inclined to delete it altogether. I'm curious if you add this to your config:
if that fixes things for you when used with
experimental_use_profile = true?Hey @bolinfest - thank's for checking in.
So, if you ran a script that would have say
#!/bin/bashas the first line, then sure, it should really just inherit because all it's doing is executing _bash script_ inside of your shell context. However, by starting a script with#!/bin/bash -l, you're going to create an entirely _new_ shell session, which doesn't inherit -- they never do, as far as my research has sorta gotten me to.I have a pretty decent explainer o3 session which i've emailed you the link to directly. That helped me get clarity in my prior understanding of it.
Ultimately, the only thing that I believe makes sense is to _not_ wrap commands in bash -lc (and i was able to do so, although not as consistently as i liked, with some very aggressive tool function tuning).
Regarding your comments about ditching the
shell_environment_policy, i think you are right that it's just not a good fit. Further, i had planned to open a new thread that talks about how currently there is no affordance for the use of aliases in local shells. e.g., here's myls:Now, because the function caller doesn't really know that, it will (and does) try to do command calls that end up with either conflicting flags or just flags that don't work anymore -- since it's not k&r ls, but a facsimile interface from eza, etc.
All of that leads me into thinking that the safest way forward is a 'blessed' buildable-onto docker image that y'all ship, with the base locked down (and with some very strict write permissions: e.g.
/usrwould be readonly, and only a mounted volume was writeable, etc) -- that would mean codex would have trust in a 'known' environment (i.e. sure, i could still possibly alias awayls, but i'd have to work at it -- so it wouldn't be something that would happen normally just because it existed before, if that makes sense). If it was simple enough to setup, then honestly it could be injected in as part of the bootstrap process. For macos, i think https://github.com/apple/container / https://github.com/apple/containerization would be a really interesting starting point, as i think you could very quickly and cheaply createenvironmentssimilar to how codex on the web works.Anyhow, happy to chat more about it, but for now it does seem like the profile stuff is more of a mess than it should be, and i'd consider rolling that PR back, as it's not really able to deliver on the promise it sets out to do, unfortunately. 🤷
@imajes Thanks for the detailed reply! What if we did
bash -cinstead ofbash -lc? For example, on your machine, what does this print when you run it in the shell:@bolinfest: well, doing that means it won't go visit
/etc/profileor/etc/bash_*which is probably a _good thing_.However, it doesn't entirely get there:
and:
What is good though is that by not creating that new login shell, it's going to at least pick up a good amount of stuff from the parent. The reason it's not picking up the
ls --> ezabit is due to that being an alias in my zsh startup scripts, so it'll never show in bash.Which is probably a good thing, because with a clean shell, you can trust commands a bit better.
However i would imagine it'd create devex challenges because one might assume that their shell (and it's idiosyncrasies) will be what codex is using, but ultimately any time it does the
bash -cprefix, that's never going to really be true.One thing i'd ask though- - since that's api side, i'm assuming there's a very heavy thumb-on-the-scale thing that says, 'if useragent == codex, always wrap whatever it comes up with in
bash -lc? I did try pretty hard to amend that via function tooling prompting, but it was pretty hit and miss.One thing we have also talked about (which I think would work here?) would be a combination of using
bash -c(instead ofbash -lc) and replaying all your aliases in the new shell.That seems like a lot of work: if i needed to create an environment with all of that in it, i should probably be expected to spin one up via a container, where i could set it up more deterministically.
Made a change to strip
bash -lcand include.zshenv, .zprofilein https://github.com/openai/codex/pull/1725OK. I just spent a couple hours trying to track this down a bit, and given i'm pretty new to the codebase, probably took far longer than it should have, but fun's fun, right? :)
@pakrym-oai: i'm using your branch right now, and it's still not doing what it should be (and certainly isn't _reporting_ what it should be).
add on to that, it looks like
sandbox-execis probably not the best way forward either.@bolinfest, @pakrym-oai: having spent (at this point) quite some time digging into this and fairly deeply refreshing my knowledge of how shells get invoked, would either of both of you be up for a quick meet/zoom to chat about it? I say that because it really might actually be the higher fidelity required to get into this-- as i don't think this is a few line fix. :)
@bolinfest - gentle nudge. I had a few further ideas about this and wanted to discuss before committing to do anything... :) if there's any way for a quick sync, that'd be really useful. Thank you!
What's blocking this issue from being fixed? Codex is completely unusable with this bug
it's still doing this occasionally. I'm on macOS, gpt-5-codex with Codex CLI v0.42 and I updated to v0.44 it's still there. and it lied when I asked it.
but I told it to force it and it realized how to remove that. should we make a PR like #1725 for zsh? @pakrym-oai
Original issue was tackled by https://github.com/openai/codex/pull/1725. Closing.