DEV Community

Cover image for Making Codex CLI and Codex.app Use mise-managed Ruby and Node.js
Takashi Masuda
Takashi Masuda

Posted on • Originally published at masutaka.net

Making Codex CLI and Codex.app Use mise-managed Ruby and Node.js

I mostly use Claude Code, but lately I've been using Codex CLI and Codex.app (hereafter "Codex") more often too. My environment is macOS.

However, after I started using mise in [2026-03-29-1], I ran into trouble because Codex wouldn't use the mise-managed Ruby, Node.js, and so on.

Here's the state I was in:

$ where ruby
/usr/bin/ruby

$ ruby --version
ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin25]
Enter fullscreen mode Exit fullscreen mode

The Solution

I solved it by adding the following to ~/.zshenv:

# When Codex CLI and Codex.app run commands, .zshrc's mise activate zsh doesn't take effect,
# so add mise shims to PATH.
if [ -n "$CODEX_SANDBOX" ]; then
  PATH=${XDG_DATA_HOME}/mise/shims:$PATH
fi
Enter fullscreen mode Exit fullscreen mode

Here's the state inside Codex after the change:

$ where ruby
/Users/masutaka/.local/share/mise/shims/ruby
/usr/bin/ruby

$ ruby --version
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +PRISM [arm64-darwin25]
Enter fullscreen mode Exit fullscreen mode

Codex's Command Execution Environment Is a Sandbox

I'd vaguely suspected this for a while, but it seems Codex's command execution environment runs inside a sandbox.

You can spot the clues from within Codex:

$ env | grep CODEX
CODEX_CI=1
CODEX_SANDBOX=seatbelt
CODEX_THREAD_ID=019e7806-6025-7c13-a3c6-a70d41c13905
Enter fullscreen mode Exit fullscreen mode

"seatbelt" refers to Apple Seatbelt, which appears to be macOS's sandboxing mechanism.

🔗 macOSで手軽にSandbox環境を構築できるApple Seatbeltの実践ガイド

しかしながら、Apple Seatbeltは公式にドキュメントを公開されておらず、非推奨とされています。一方で実際には多くのアプリケーションやツールで使用されています。

(English translation) However, Apple Seatbelt has no officially published documentation and is considered deprecated. Yet in practice, it's used by many applications and tools.

I see...

According to this article, Claude Code also adopts Apple Seatbelt, and I confirmed that it can be enabled with /sandbox (see the official documentation).

Coming from a background of being used to Claude Code, Codex's sandbox is hard to wrap my head around, but the following article covers it in detail. Much appreciated.

🔗 [Codex] sandbox実行の仕組みと設定方法を完全に理解する

Codex also seems to restrict network access by default. Come to think of it, I remembered that I'd previously set the following in ~/.codex/config.toml:

[sandbox_workspace_write]
network_access = true
Enter fullscreen mode Exit fullscreen mode

The Road to the Solution

At first I tried to solve it with a setting like this in ~/.codex/config.toml, but it didn't work:

[shell_environment_policy.set]
PATH = "/Users/masutaka/.local/share/mise/shims/ruby:(the existing PATH settings hardcoded here)"
Enter fullscreen mode Exit fullscreen mode

As I dug deeper, it occurred to me: "Doesn't ~/.zshenv get loaded every time, even inside the sandbox? If Codex-related environment variables are defined, I should be able to handle it in ~/.zshenv." That led me to the solution.

The reason eval "$(mise activate zsh)" in ~/.zshrc doesn't take effect is that ~/.zshrc is only loaded for interactive shells. Codex appears to run commands in non-interactive shells, so the settings in ~/.zshenv, which is loaded every time zsh starts, are what take effect.

I also came up with the idea of moving eval "$(mise activate zsh)" itself into ~/.zshenv, and it did actually work. However, I think this isn't a good approach. The activate PATH method is a mechanism that updates environment variables every time the prompt is displayed, so using it in a non-interactive shell with no prompt falls outside its intended purpose.

mise also recommends shims for non-interactive environments (scripts, IDEs, CI), so I followed that here. It's the same approach of adding shims to PATH that I adopted for Emacs in [2026-03-29-1].

I wanted to avoid hardcoding PATH into ~/.codex/config.toml since that would mean duplicate management with ~/.zshenv, so I'm glad it settled into a clean form.

Conclusion

I summarized how to make Codex CLI and Codex.app use mise-managed Ruby and Node.js.

I think mise is gradually gaining adoption, but I couldn't find an answer by Googling and wondered how everyone else handles this, so I wrote this short article. I hope it helps someone.

Related

Top comments (0)