Shell tool call panics when any environment variable is not valid UTF-8
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 85/100
Research direction
Start at codex_protocol::shell_environment::create_env and follow its caller in codex_core::exec_env::create_env, focusing on how inherited environment entries are converted. Reproduce the issue with the provided Python command and an invalid UTF-8 value, then verify that the shell command runs successfully without a panic.
Written by the indexing model from the issue text.
Description
Summary
Codex panics on every shell tool call if any environment variable contains bytes that are not valid UTF-8. The tool call aborts, the model only sees "the tool aborted", and no command can run until the offending variable is removed from the environment.
Environment
- codex-cli 0.160.0 (brew cask,
/opt/homebrew/bin/codex), latest stable at the time of writing - macOS 15.6.1, arm64
- Reproduced with
codex exec, and in the Codex desktop app's Bash tool with the same panic - Not caused by hooks or any third-party hook: reproduced with an isolated
CODEX_HOMEcontaining onlyconfig.toml+auth.json(nohooks.json), and with no hook configured at all
Reproduction
- Put a non-UTF-8 value into any environment variable. Real-world trigger: a variable exported from a legacy config file that is not valid UTF-8. Minimal synthetic version:
import os, pathlib, subprocess, tempfile
d = tempfile.mkdtemp()
pathlib.Path(d, "a").touch()
env = dict(os.environb)
env[b"BADVAR"] = b"\xff" # a single invalid byte is enough
subprocess.run(
["codex", "exec", "--skip-git-repo-check", "-C", d, f"Run: mv {d}/a {d}/b"],
env=env,
)
- Codex starts normally, issues the shell call, and the call aborts.
Actual result
thread 'tokio-rt-worker' (10151524) panicked at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/env.rs:162:83:
called `Result::unwrap()` on an `Err` value: "\xFF"
stack backtrace:
3: <std::env::Vars as core::iter::traits::iterator::Iterator>::next
4: codex_protocol::shell_environment::create_env
5: codex_core::exec_env::create_env
...
ERROR codex_core::util: in-flight tool future failed during drain:
Fatal error: tool task failed to receive: JoinError::Panic(Id(1666), "called `Result::unwrap()` on an `Err` value: \"\\xFF\"", ...)
(Frame names from a RUST_BACKTRACE=1 run; some neighbouring frames may be misattributed by inlining, but codex_protocol::shell_environment::create_env is consistent across runs.)
The model sees only that the command was aborted and cannot distinguish this from a permission denial. Every subsequent shell call panics identically; in my run three consecutive attempts all aborted, and the target command never executed.
Expected
Codex should tolerate non-UTF-8 environment values. The simplest correct behaviours would be to pass them through untouched (they are legal in a POSIX environment), pass them lossily, or drop just those entries. Panicking the runtime task is never appropriate here.
Root cause / suggested fix
std::env::vars() is used while assembling the environment for the child shell (codex_protocol::shell_environment::create_env). env::vars() converts each entry with OsString::into_string().unwrap(), so a single non-UTF-8 value panics the tokio task and the tool future fails with JoinError::Panic.
Switching that call site to std::env::vars_os() and converting with to_string_lossy(), or filtering out entries that fail into_string(), would remove the panic.
Impact
Any user with a non-UTF-8 value in their environment, which is common with legacy locale tooling, mojibake config files, or variables inherited from an older shell, gets a completely unusable Codex for shell work. The failure message points at nothing in particular, so the actual cause is hard to find.
- Dominant language
- Rust
- Stars
- 129k
- Forks
- 20.3k
- Avg merge
- 1m
- Merged PRs (30d)
- 998
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
codex-skills-extension: pass ModelInfo context window in SkillsExtension::contribute_thread_contextOpenbug CLI context skills
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
documentation
Difficulty 1/5 Under an hour Newbie friendliness 86/100
Maintainers usually reply within 1 day
-
apply_patch drops trailing spaces from filenamesPossibly taken @akhil9tiet claimed this 2 days ago. Openbug tool-calls
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
openai/codex#53245 · 2 comments ·
Maintainers usually reply within 1 day
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
openai/codex#53227 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement extension
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
Similar issues
-
Custom hosts written as trailing-dot FQDNs (`host.local.`) aren't detected as local backendsPossibly taken @roboomp claimed this today. Openbug prio:p2 providers triaged
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
can1357/oh-my-pi#15798 · 3 comments ·
Maintainers usually reply within 1 day
-
requires-triage
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
apache/datafusion-comet#7001 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
builtin-port enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
cmlarsen/writemorebetter#235 ·
Maintainers usually reply within 1 day
-
Add a Storybook section to CONTRIBUTING.mdPossibly taken @ChanakyaG2004 claimed this today. Opendocumentation good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
FlowwStar/FlowStar#995 · 2 comments ·
Maintainers usually reply within 1 day