Skip to content

Codex runs commands via bash --login and drops per-project env #4843

Open

Description

@apt-get-coke

Version

codex-cli 0.44.0

Repro steps

  1. In a repo that relies on direnv (e.g. .envrc runs use flake .) so project tools live under .devenv/profile/bin.
  2. cd into that repo and launch codex.
  3. Ask Codex to run one of those project helpers (e.g. ensure-python-stack) or just codex -- /bin/echo "/home/julien/.nix-profile/bin:/home/julien/.local/bin:/home/julien/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games".

Expected

Codex keeps the direnv-injected PATH (worked in 0.42.0); project binaries stay visible.

Actual

0.44.0 now spawns every command with bash --login -c … (see PR #4612). The login shell starts in /home/julien, the PATH is rebuilt without .devenv/profile/bin, and project helpers hit "command not found". To work around it I have to wrap every command in direnv exec . …, which re-runs the heavy enter-shell hook and makes Codex painfully slow. tmux titles flip to "home" for the same reason.

Could you drop the login shell (or add a config flag to keep the inherited environment)? This change effectively breaks Codex for direnv/devenv workflows.

Activity

  1. github-actions commented on Oct 6, 2025

    @github-actions
    Contributor

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

    Powered by Codex Action

  2. changed the title [-]codex 0.44.0 runs commands via bash --login and drops per-project env[/-] [+]Codex runs commands via bash --login and drops per-project env[/+] on Oct 6, 2025
  3. o1lo01ol1o commented on Oct 14, 2025

    @o1lo01ol1o

    Related #4667

  4. o1lo01ol1o commented on Oct 14, 2025

    @o1lo01ol1o

    @apt-get-coke Can you confirm this worked in 0.42.0?

    I have, for example:

    % which codex
    /nix/store/67annmfwgz60y8p97ysddi9bvc7lcy7r-codex-0.42.0/bin/codex
    % which foo
    /nix/store/grqqy0gpv4hlnix8qhk1h0yklizkrd7r-foo-2.79.3/bin/foo
    
    % codex
    {...}
    
    ▌ what's the output of which foo?
    
    • Ran which foo
    
    > faust isn’t on PATH here (which foo returned exit code 1). Enter your devenv shell so
      the toolchain scripts—including foo and build-foo—become available.
    
  5. apt-get-coke commented on Oct 14, 2025

    @apt-get-coke
    Author

    @apt-get-coke Can you confirm this worked in 0.42.0?

    I have, for example:

    % which codex
    /nix/store/67annmfwgz60y8p97ysddi9bvc7lcy7r-codex-0.42.0/bin/codex
    % which foo
    /nix/store/grqqy0gpv4hlnix8qhk1h0yklizkrd7r-foo-2.79.3/bin/foo
    
    % codex
    {...}
    
    ▌ what's the output of which foo?
    
    • Ran which foo
    
    > faust isn’t on PATH here (which foo returned exit code 1). Enter your devenv shell so
      the toolchain scripts—including foo and build-foo—become available.
    

    Yes, it still works for us on 0.42.0. Example:

    $ codex --version
    codex version 0.42.0
    $ pwd
    /path/to/project
    $ codex
    codex> which foo
    /path/to/project/.direnv/bin/foo
    codex> exit

    That project’s .envrc runs direnv/devenv so the toolchain ends up in .direnv/bin. With codex 0.44.0 the executable launches the
    shell with --login, the working directory resets to $HOME, .envrc never runs, and the PATH entry disappears:

    $ codex --version
    codex version 0.44.0
    $ codex
    codex> pwd
    $HOME
    codex> which foo
    which: no foo in ...

    If we cd back into the project after codex starts and run direnv reload, the PATH comes back. The regression appears tied to the
    new --login behavior wiping out the inherited cwd/direnv environment.

  6. apt-get-coke commented on Oct 14, 2025

    @apt-get-coke
    Author

    Related #4667

    Nope—#4667 is a feature request about letting codex run commands with a user-supplied PATH so it can see toolchains inside a
    sandbox. Our issue is a regression in 0.44: codex now launches the shell with --login, which resets the working directory to
    $HOME, so .envrc doesn’t run and our existing PATH entries aren’t retained. Different problem, unfortunately. :)

  7. guidomb commented on Nov 10, 2025

    @guidomb

    Does anyone has a way of working around this issue? We face the same issue and would be helpful to be able to use codex with devenv

  8. apt-get-coke commented on Nov 12, 2025

    @apt-get-coke
    Author

    Does anyone has a way of working around this issue? We face the same issue and would be helpful to be able to use codex with devenv

    We hit the same problem and never found a reliable fix, so we dropped per-project nix/devenv. Each Python repo now ships with " + " for reproducible envs without Codex choking on nix build steps. We still keep nix at the user level for shared dev tools, but project envs are fully uv-driven. It’s been better for us because syncs/locks much faster than nix, Codex Cloud can run immediately, and our CI runners spend less time rebuilding derivations, so overall there’s less friction while we keep the reproducibility we cared about.

  9. o1lo01ol1o commented on Nov 12, 2025

    @o1lo01ol1o
  10. guidomb commented on Nov 14, 2025

    @guidomb

    Well I ended up adding the following to ~/.codex/config.toml is

    [shell_environment_policy]
    inherit = "all"
    ignore_default_excludes = true

    and then running codex with codex --sandbox danger-full-access

    This results in our devenv and .env loaded via direnv working

  11. etiennecrb commented on Nov 14, 2025

    @etiennecrb

    @guidomb It doesn't work for me on macos

    My only workaround is to set manually the must have variables I need:

    [shell_environment_policy]
    # Temporary workaround until codex is compatible with direnv again
    # https://github.com/openai/codex/issues/4210
    set = { MY_VAR = "foo" }
  12. guidomb commented on Nov 14, 2025

    @guidomb

    @etiennecrb Mmm interesting I also run on macOS.

    devenv --version
    devenv 1.7.0 (aarch64-darwin)
    

    might be related with my particular env, this is my .envrc

    export DIRENV_WARN_TIMEOUT=20s
    
    eval "$(devenv direnvrc)"
    
    # The use_devenv function supports passing flags to the devenv command
    # For example: use devenv --impure --option services.postgres.enable:bool true
    use devenv --option dotenv.enable:bool true
    
  13. ak2766 commented on Dec 23, 2025

    @ak2766

    I was hoping to see resolution on this but still no bueno.

    Let me try what @guidomb suggested above and see if this resolves my current issue which is documented below:

    terminal text scrape
    > pwd
    /home/akk/source/profiler
    > 
    > ls | head -n 5
    stats.sh
    wrk.log
    > 
    > ls ${HOME} | head -n 5
    __a1
    __a2
    __a3
    __a4
    __a5
    > 
    > codex
    ╭────────────────────────────────────────────────────╮
    │ >_ OpenAI Codex (v0.77.0)                          │
    │                                                    │
    │ model:     gpt-5.2-codex medium   /model to change │
    │ directory: ~/source/profiler                       │
    ╰────────────────────────────────────────────────────╯
    
      Tip: You can run any shell command from Codex using ! (e.g. !ls)
    
    
    › Can you please show me the first 5 files in the current project directory?
    
    
    • Explored
      └ List ls -1
    
    ─ Worked for 5s ────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    
    • First five entries (sorted by name):
    
      1. __a1
      2. __a2
      3. __a3
      4. __a4
      5. __a5
    
    Terminal screenshot Image
  14. pasky commented on Jan 2, 2026

    @pasky

    Note that both the shell being started being login shell and being interactive is an issue...

    1. The shell tool behaves weirdly in case you do something non-trivial in your .profile (echo $TERM, uptime, fortune, ...), e.g. my output looks like this:
    • I'm running a shell command that prints $0, the login_shell shell option, and the current process args with the default login shell setting to confirm if it runs as a login shell and then will summarize the observed output.
    
    $ echo "0=$0"; shopt login_shell; ps -o args= -p $$
    command timed out after 10005 milliseconds
    TERM=tmux-256color
    
    "If you want to eat hippopotamus, you've got to pay the freight."
            -- attributed to an IBM guy, about why IBM software uses so much memory
    
    
     20:26:25 up 134 days, 18:57, 13 users,  load average: 0.22, 0.37, 0.48
    ✗ (124) • 10.01s
    
    1. Using interactive shell makes codex completely broken on my machine, since the tool hangs when it tries to execute it. Codex says:
    The hang comes from your login shell running pyenv init - (via ~/.profile → ~/.bashrc). That invokes pyenv rehash, which tries to write ~/.pyenv/shims/.pyenv-shim; in the Codex sandbox that path isn’t writable, so pyenv rehash loops for up to 60s
      waiting on a lock and the CLI times out (~10s) instead.
    
    1. No other AI agent CLI I tried (claude code, gemini, ampcode, ...) uses login / interactive shell. It's not really clear to me why codex is trying to use interactive shell at all...
  15. pasky commented on Jan 2, 2026

    @pasky

    Hmm, it seems this was introduced in #1725 - @pakrym-oai could you please take a look? Why is Codex behaving differently from other CLIs in this regard? Would it make sense to have this configurable?

  16. ryoppippi commented on Jun 23, 2026

    @ryoppippi

    any updates?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtool-callsIssues related to tool calling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions