Skip to content

fix: surface the real task error in the stop-review gate instead of stderr noise#442

Open
fabiogioachin wants to merge 1 commit into
openai:mainfrom
fabiogioachin:fix/stop-gate-surface-real-error
Open

fix: surface the real task error in the stop-review gate instead of stderr noise#442
fabiogioachin wants to merge 1 commit into
openai:mainfrom
fabiogioachin:fix/stop-gate-surface-real-error

Conversation

@fabiogioachin

@fabiogioachin fabiogioachin commented Jul 7, 2026

Copy link
Copy Markdown

Problem

When the stop-review gate's companion task fails (codex-companion.mjs task --json exits non-zero), the hook reports result.stderr || result.stdout as the failure reason:

const detail = String(result.stderr || result.stdout || "").trim();

On some setups (observed on Windows + recent Node), the child's stderr contains only Node runtime noise:

(node:10964) [DEP0190] DeprecationWarning: Passing args to a child process with shell option true can lead to security vulnerabilities, as the arguments are not escaped, only concatenated.

Since a non-empty stderr wins over stdout, this deprecation warning masks the real error, which is only available as the human-readable message of the failed run. The user sees the gate block with a DeprecationWarning as the "reason" and has no idea what actually failed.

Real-world example: the actual failure was a Codex usage-limit error (You've hit your usage limit... try again at Aug 5th), but the hook surfaced only the DEP0190 line. Diagnosing it required digging into the job log files under the plugin state directory.

Fix

Two small, backward-compatible changes:

  1. codex-companion.mjsrunForegroundCommand now includes the human-readable rendered message in the --json payload (additive field; existing consumers that parse rawOutput, status, etc. are unaffected).

  2. stop-review-gate-hook.mjs — on non-zero exit, the hook now resolves the failure detail in order of usefulness:

    1. payload.rendered parsed from the JSON stdout (the real error),
    2. stderr with DeprecationWarning noise lines filtered out,
    3. raw stdout as a last resort.

Before / after

Before:

The stop-time Codex review task failed: (node:19580) [DEP0190] DeprecationWarning: Passing args to a child process with shell option true...

After:

The stop-time Codex review task failed: You've hit your usage limit. Upgrade to Plus to continue using Codex (https://chatgpt.com/explore/plus), or try again at Aug 5th, 2026 3:58 AM.

Verified end-to-end on Windows 11 / Node against a live failing Codex run (usage-limit error): the gate now blocks with the actual cause in reason, exit code 0, valid decision JSON. node --test suite passes locally.

🤖 Generated with Claude Code

…tderr noise

When the companion task fails, the stop-review gate reported
result.stderr || result.stdout. On setups where the child's stderr
contains only Node runtime noise (e.g. the DEP0190 DeprecationWarning
emitted for shell:true spawns), that noise masked the actual failure
reason, which was only available as the run's rendered message.

- codex-companion.mjs: include the human-readable rendered message in
  the --json payload of foreground commands (additive field).
- stop-review-gate-hook.mjs: on non-zero exit, prefer payload.rendered
  from the JSON stdout, then stderr with DeprecationWarning lines
  filtered out, then raw stdout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@fabiogioachin fabiogioachin requested a review from a team July 7, 2026 02:22
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.

1 participant