codex - 💡(How to fix) Fix Add `stdin` field to `exec_command` for reliable multiline script execution [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openai/codex#19119Fetched 2026-04-24 06:00:33
View on GitHub
Comments
2
Participants
2
Timeline
6
Reactions
0
Author
Timeline (top)
labeled ×3commented ×2unlabeled ×1

Error Message

ERROR codex_core::tools::router: error=exec_command failed for /bin/zsh -lc "python3 - <<'PY' ...

Fix Action

Fix / Workaround

Current workarounds and why they fall short

Code Example

/bin/zsh -lc "python3 - <<'PY'\nimport json\ndata = {\"key\": \"value\"}\nprint(json.dumps(data))\nPY"

---

ERROR codex_core::tools::router:
  error=exec_command failed for `/bin/zsh -lc "python3 - <<'PY' ...`

---

{
  "cmd": "python3 -",
  "stdin": "import json\ndata = {\"key\": \"value\"}\nprint(json.dumps(data))\n"
}
RAW_BUFFERClick to expand / collapse

What variant of Codex are you using?

CLI (via codex-acp agent runtime)

What feature would you like to see?

The problem

When the agent needs to run a multiline script (Python, awk, Node, etc.), the only option today is to encode the entire script as a shell -c string:

/bin/zsh -lc "python3 - <<'PY'\nimport json\ndata = {\"key\": \"value\"}\nprint(json.dumps(data))\nPY"

This is fragile. The script body passes through shell parsing, so any dollar signs, backticks, double quotes, or backslashes in the script interact with the shell's own syntax. The LLM has to get the escaping exactly right for the specific shell, and it frequently doesn't — leading to failed commands, retries, and wasted tokens.

Observed in production (codex-acp):

ERROR codex_core::tools::router:
  error=exec_command failed for `/bin/zsh -lc "python3 - <<'PY' ...`

This pattern repeated 4 times in a ~2 hour window as the agent kept retrying with different escaping strategies.

What would help

An optional stdin field on exec_command, so the agent can do:

{
  "cmd": "python3 -",
  "stdin": "import json\ndata = {\"key\": \"value\"}\nprint(json.dumps(data))\n"
}

The script body goes directly to the process's stdin pipe, never touches shell parsing. No escaping needed, works with any interpreter that reads from stdin (python3 -, bash -s, node -e, awk).

Current workarounds and why they fall short

  • heredoc in shell -c: fragile escaping, shell-dependent behavior
  • Write to temp file, then execute: blocked by sandbox when /tmp and $TMPDIR are excluded from writable paths
  • write_stdin on a separate call: requires two tool calls instead of one, and until recently didn't work on non-TTY sessions at all (see https://github.com/openai/codex/issues/18578)

Scope

The plumbing for this mostly exists already. Non-TTY processes are spawned with piped stdin (or will be, once https://github.com/openai/codex/issues/18578 lands). The change would be:

  1. Add an optional stdin field to ExecCommandArgs in unified_exec.rs
  2. After spawning the process, write the stdin content to the pipe and close it
  3. Collect output as usual

This keeps the API backward-compatible — omitting stdin preserves current behavior.

Platform

  • Darwin 25.3.0 arm64 arm
  • Observed via codex-acp agent runtime, codex rust-v0.117.0

Additional information

No response

extent analysis

TL;DR

Adding an optional stdin field to exec_command would allow scripts to be passed directly to the process's stdin pipe, avoiding shell parsing and escaping issues.

Guidance

  • Review the proposed change to add an stdin field to ExecCommandArgs in unified_exec.rs to determine its feasibility and potential impact on existing functionality.
  • Consider the benefits of passing scripts directly to the process's stdin pipe, including avoiding shell-dependent behavior and escaping issues.
  • Evaluate the potential effects of this change on non-TTY sessions, given the recent resolution of https://github.com/openai/codex/issues/18578.
  • Assess the backward compatibility of the proposed change, as omitting the stdin field would preserve current behavior.

Example

{
  "cmd": "python3 -",
  "stdin": "import json\ndata = {\"key\": \"value\"}\nprint(json.dumps(data))\n"
}

This example demonstrates how the proposed stdin field could be used to pass a Python script directly to the python3 process.

Notes

The proposed change appears to be a targeted solution to the issue, but its implementation and testing would require careful consideration of the existing codebase and potential edge cases.

Recommendation

Apply the proposed workaround by adding an optional stdin field to exec_command, as it addresses the root cause of the issue and provides a more robust solution than current workarounds.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING