Skip to content

fix(codex-rescue): append </dev/null to codex-companion task invocation#274

Open
hobaratio wants to merge 1 commit intoopenai:mainfrom
hobaratio:fix/codex-rescue-stdin-hang
Open

fix(codex-rescue): append </dev/null to codex-companion task invocation#274
hobaratio wants to merge 1 commit intoopenai:mainfrom
hobaratio:fix/codex-rescue-stdin-hang

Conversation

@hobaratio
Copy link
Copy Markdown

Summary

Append </dev/null to the node codex-companion.mjs task ... Bash invocation documented in:

  • plugins/codex/agents/codex-rescue.md
  • plugins/codex/skills/codex-cli-runtime/SKILL.md

Without this stdin redirect, the node process can hang when stdin is left attached to the parent shell. In Claude Code this surfaces as Reading additional input from stdin... errors that block long-running Codex dispatches at indeterminate points (post-fixture, post-commit, etc.) — the wrapper reports "completed" but the underlying node process never returns to terminal state.

Reproducer

Two consecutive Codex dispatches in a downstream repo (2026-04-27) where Codex:

  • Correctly wrote all expected files
  • Ran regression tests to PASS (verified via codex-companion.mjs status progressPreview)
  • Then hung 30+ minutes before the would-be git commit/git push step

External codex-companion.mjs status --json confirmed the job was still listed as "status": "running" with the node process alive. Killing the process unblocked the hang and the partial work was visible on disk. Appending </dev/null to the invocation in the local plugin cache prevented the hang on subsequent dispatches.

Diff

--- a/plugins/codex/agents/codex-rescue.md
+++ b/plugins/codex/agents/codex-rescue.md
@@ -19,7 +19,8 @@
 
 Forwarding rules:
 
-- Use exactly one `Bash` call to invoke `node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" task ...`.
+- Use exactly one `Bash` call to invoke `node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" task ... </dev/null`.
+- Always append `</dev/null` to the Bash invocation. Without it the codex-companion node process can hang reading from stdin (Codex skill execution often hangs in Claude Code with "Reading additional input from stdin..." errors when stdin is left attached to the parent shell).

--- a/plugins/codex/skills/codex-cli-runtime/SKILL.md
+++ b/plugins/codex/skills/codex-cli-runtime/SKILL.md
@@ -9,7 +9,9 @@
 Use this skill only inside the \`codex:codex-rescue\` subagent.
 
 Primary helper:
-- \`node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" task "<raw arguments>"\`
+- \`node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" task "<raw arguments>" </dev/null\`
+
+The \`</dev/null\` redirect is mandatory. Without it the codex-companion node process can hang reading from stdin (Codex skill execution often hangs in Claude Code with "Reading additional input from stdin..." errors when stdin is left attached to the parent shell).

Why this is safe

  • The node codex-companion.mjs task invocation is a forwarder — it does not itself read from stdin meaningfully. The node child processes Codex spawns also do not depend on the parent's stdin being attached.
  • The </dev/null redirect only affects the spawned process's stdin (any read returns EOF immediately). It does not affect arguments, env vars, output, or the parent shell.
  • Standard pattern for non-interactive shell-spawned node processes.

Test plan

  • Existing dispatch behavior unchanged when stdin is already detached (no regression)
  • Long-running dispatches no longer hang post-fixture / post-commit when invoked from Claude Code
  • Background mode (--background) and foreground mode both unaffected by the redirect

The patch is minimal — two file edits, 5 lines added — and includes a short inline rationale so a future cleanup pass doesn't strip the redirect without context.

Without this redirect, the `node codex-companion.mjs task ...` Bash
invocation can hang when stdin is left attached to the parent shell.
This manifests in Claude Code as "Reading additional input from
stdin..." errors that block long-running Codex dispatches at
indeterminate points (post-fixture, post-commit, etc.) — the wrapper
reports "completed" but the underlying node process never returns.

Reproduced in two consecutive Codex dispatches (clod repo, 2026-04-27)
where Codex correctly wrote all expected files + ran regression tests
to PASS, then hung 30+ minutes before the would-be commit/push step.
External `codex-companion.mjs status --json` confirmed the job was
still listed as "running" with the node process attached. Killing the
node process unblocked the hang; appending `</dev/null` to the
invocation prevents it entirely.

Patches both `agents/codex-rescue.md` (the agent template the rescue
subagent follows) and `skills/codex-cli-runtime/SKILL.md` (the skill
contract that documents the canonical helper invocation). Also adds
a short rationale comment in each file so the redirect doesn't get
removed in a future cleanup.
@hobaratio hobaratio requested a review from a team April 27, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants