/codex: an unguarded mktemp still hands codex an empty stderr path (fail closed like the other skills)
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
**Version:** gstack 1.87.3.0 (85b8c038), macOS (Darwin 25.5), zsh 5.9 and bash 3.2, codex-cli 0.153.4
1.64.0.0 fixed the BSD mktemp suffix bug (#2091, #2370). Thank you. One path to the same symptom is still open: the `/codex` sections never check whether `mktemp` succeeded.
```
codex/sections/review-mode.md.tmpl TMPERR=$(mktemp "$TMP_ROOT/codex-err-XXXXXX")
_PROMPT_FILE=$(mktemp "$TMP_ROOT/codex-prompt-XXXXXX")
codex/sections/consult-mode.md.tmpl TMPRESP=$(mktemp "$TMP_ROOT/codex-resp-XXXXXX")
TMPERR=$(mktemp "$TMP_ROOT/codex-err-XXXXXX")
codex/sections/challenge-mode.md.tmpl TMPERR=${TMPERR:-$(mktemp "$TMP_ROOT/codex-err-XXXXXX")}
```
When `mktemp` fails, the variable is empty. That happens when TMP_ROOT is unwritable or full, or when a sandbox sets a TMPDIR that doesn't exist. `2>"$TMPERR"` then fails before codex starts. Review mode prints `[codex exit 1] no stderr captured` (review-mode.md:61), which reads as a Codex failure, exactly as #2091 did.
**Repro.** zsh and bash give the same result:
```
$ TMP_ROOT=/nonexistent
$ TMPERR=$(mktemp "$TMP_ROOT/codex-err-XXXXXX")
mktemp: mkstemp failed on /nonexistent/codex-err-Jv5ShC: No such file or directory
$ true 2>"$TMPERR"; echo "exit=$?"
zsh:1: no such file or directory:
exit=1
```
**Other skills already fail closed here:**
- plan-design-review, autoplan (the ceo, eng, dx and design phases) and design-consultation use `_OUTSIDE_TMP=$(mktemp -d …) || exit 1`.
- ship (the PR body scan) uses `PR_BODY_FILE=$(mktemp) || { echo "ERROR: mktemp failed — …" >&2; exit 1; }`.
**Proposal:** give the five `/codex` mktemp calls the same guard, for example:
```
TMPERR=$(mktemp "$TMP_ROOT/codex-err-XXXXXX") || { echo "ERROR: mktemp failed in TMP_ROOT=$TMP_ROOT; not running codex without its temp file" >&2; exit 1; }
```
Then pin it next to test/mktemp-portability.test.ts: every `$(mktemp` assignment in `codex/sections/*.tmpl` must be followed by `||`.
We carried this guard as a local patch on 1.60.1.0, together with the X-run fix. After upgrading to 1.87.3.0, the guard is the only part upstream lacks.
Contributor guide
Research direction
Start with the five mktemp assignments in codex/sections/review-mode.md.tmpl, consult-mode.md.tmpl, and challenge-mode.md.tmpl, then read test/mktemp-portability.test.ts. Verify each assignment fails closed when mktemp returns an error, before the Codex command or stderr redirection runs, and use the portability test to confirm every assignment is guarded.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- shell, typescript
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100